//==============================================================================
//
//  File        : sensor_GC0328.c
//  Description : Firmware Sensor Control File
//  Author      : Philip Lin
//  Revision    : 1.0
//
//=============================================================================

#include "includes_fw.h"
#if defined(DSC_MP3_P_FW)||defined(VIDEO_AMR_R_FW)||defined(VIDEO_AAC_R_FW)||(SENSOR_EN)
#include "config_fw.h"

#if BIND_SENSOR_GC0328

#include "lib_retina.h"
#include "reg_retina.h"

#include "mmp_reg_vif.h"
#include "mmp_reg_scaler.h"
#include "mmp_reg_gpio.h"
#include "mmp_reg_rawproc.h"

#include "mmpf_sensor.h"
#include "mmpf_hif.h"
#include "mmpf_i2cm.h"
#include "mmpf_vif.h"
#include "isp_if.h"
#include "mmpf_usbpccam.h"

#include "mmp_reg_i2cm.h"
#include "mmps_3gprecd.h"
#include "sensor_GC0328.h"
#include "hdm_ctl.h"
#include "mmpf_dram.h"
#include "motor_ctl.h"
#include "flash_ctl.h"
#include "mmpf_pll.h"

static MMPF_I2CM_ATTRIBUTE m_snr_I2cmAttribute = {
            SENSOR_I2CM_ID,
            SENSOR_I2C_ADDR_GC0328, 
            8, 
            8, 
            0, 
            MMP_FALSE, 
            MMP_FALSE, 
            MMP_FALSE,
            MMP_FALSE, 
            0, 
            0, 
            0, 
            MMPF_I2CM_SPEED_HW_250K, 
            NULL, 
            NULL
 };

#if (CUSTOMER == ASU)
#if (SENSOR_IF != SENSOR_IF_PARALLEL)
    #undef SENSOR_IF 
    #define SENSOR_IF                (SENSOR_IF_PARALLEL)
#endif
#endif
            
#ifndef SENSOR_ID_GC0328
    #define SENSOR_ID_GC0328 0
#endif

MMP_ULONG g_SNR_LineCntPerSec = 1;

static MMP_UBYTE   vif_id = 0;

extern MMP_USHORT  gsSensorPreviewWidth[], gsSensorPreviewHeight[];
extern MMP_USHORT  gsCurPreviewMode, gsCurPhaseCount;
//extern MMP_USHORT  gsSensorMode;
extern MMP_USHORT  m_usVideoQuality;
extern MMP_USHORT  m_gsISPCoreID;

extern MMPS_3GPRECD_VIDEO_FORMAT m_VideoFmt;
extern MMP_BOOL    gbAutoFocus;

extern MMP_USHORT m_usResolType;
extern MMP_ULONG   glPccamResolution;

MMP_LONG gldummy[5] = {0};

MMP_USHORT snr_1, snr_2, snr_3, snr_4, snr_5;

#if (IQ_TABLE_LOAD_FROM_FLASH == 0)
ISP_UINT8 Sensor_IQ_CompressedText[] = {
NULL
//#include "isp_8451_iq_data_v2_GC0328.xls.iq.txt"
};
#endif

#define  SENSOR_ROTATE_180    0   

#define BASE_SHUTTER_50HZ		248
#define BASE_SHUTTER_60HZ		207

#define SENSOR_OUTPUT       (1)  // 0: 640x480@30fps full mode, 
                                 // 1: 320x240@30fps binning mode, 
                                 // 2: 160x120@30fps binning mode, 
                                 // 3: 320x320@60fps cropping mode, 
                                 // 4: 320x240@60fps cropping mode

#define SENSOR_RESOLUTION_WIDTH  320
#define SENSOR_RESOLUTION_HEIGHT 240
#define NEW_SENSOR_SETTING            0

void SNR_GC0328_SetSensorResolution_Customer(ISP_SENSOR_RESOL res);
void SNR_GC0328_InitSensor_Customer(void);
#if SUPPORT_AUTO_FOCUS
void MOTOR_GC0328_VCM_InitMotor_Customer(void);
void MOTOR_GC0328_VCM_SetAFPosition_Customer(MMP_USHORT af_pos);
#endif

void MMPF_SetPrivacyMask(ISP_UINT8 en, ISP_UINT8* privacymask);
ISP_UINT8 en_flag, privacymask[35];
static VENUS_SYSTEM_MODE gSystemMode;

//------------------------------------------------------------------------------
//  Function    : GC0328_Sensor_PreviewMode
//  Description :
//------------------------------------------------------------------------------
extern MMP_BYTE gbSignalType;
extern MMPF_SENSOR_FUNCTION *gsSensorFunction ;
static void GC0328_Sensor_PreviewMode(MMP_USHORT usPreviewmode)
{
    gsCurPreviewMode = usPreviewmode;
    ISP_IF_AE_SetMinFPSx10(150);
    switch (usPreviewmode) {
    case 0:
        RTNA_DBG_Str(3, "Sensor VGA (640x480) preview mode\r\n");
        //ISP_IF_3A_Control(ISP_3A_DISABLE); //patrick@100518
        gsSensorFunction->MMPF_Sensor_Set3AStatus(MMP_FALSE);

        gSystemMode = VENUS_SYSTEM_MODE_SNAPSHOT;//ISP_IF_SNR_SetBeforeCapture();
        ISP_IF_IQ_SetSysMode(0); //Steven NOTE:please reference excel define: 0=capture, 1=preview, 2=video....
        SNR_GC0328_SetSensorResolution_Customer(ISP_SENSOR_RESOL_640x480);

        //set color transform 16 ~ 235
        MMPF_Scaler_SetOutputColor(MMPF_SCALER_PATH_1, MMP_TRUE, MMPF_SCALER_COLRMTX_BT601);

        ISP_IF_AE_SetFPS(30);
        //ISP_IF_3A_Control(ISP_3A_ENABLE); //patrick@100518
        gsSensorFunction->MMPF_Sensor_Set3AStatus(MMP_TRUE);
        break;

    case 1:
        RTNA_DBG_Str(0, "Sensor VGA (640x480) mode\r\n");
        RTNA_DBG_Str(0, "SENSOR_VIDEO_MODE\r\n");
        //ISP_IF_3A_Control(ISP_3A_DISABLE); //patrick@100518
        gsSensorFunction->MMPF_Sensor_Set3AStatus(MMP_FALSE);

        gSystemMode = VENUS_SYSTEM_MODE_PREVIEW;//ISP_IF_SNR_SetBeforePreview();
        ISP_IF_IQ_SetSysMode(1); //Steven NOTE:please reference excel define: 0=capture, 1=preview, 2=video....
        SNR_GC0328_SetSensorResolution_Customer(ISP_SENSOR_RESOL_640x480);

#if 0	
        MMPF_VIF_GetVIFGrabResolution(&ulWidth, &ulHeight);
        dbg_printf(3, "[2] ulWidth = %d, ulHeight = %d\r\n", ulWidth, ulHeight); 
#endif

        //set color transform 16 ~ 235
        MMPF_Scaler_SetOutputColor(MMPF_SCALER_PATH_1, MMP_TRUE, MMPF_SCALER_COLRMTX_BT601);

        ISP_IF_AE_SetFPS(30);

        //ISP_IF_3A_Control(ISP_3A_ENABLE);
        gsSensorFunction->MMPF_Sensor_Set3AStatus(MMP_TRUE);
        break;
    }
}
extern void GPIO_OutputControl(MMP_UBYTE num, MMP_UBYTE status);
extern volatile MMP_UBYTE   gbDramID;
//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_Initialize
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_Initialize_GC0328(void)
{
    AITPS_VIF   pVIF = AITC_BASE_VIF;
    RES_TYPE_CFG *cur_res;

    RTNA_DBG_Str(0, "MMPF_Sensor_Initialize_GC0328...Begin\r\n");

    //Init globol variable used by DSC
    gsSensorPreviewWidth[0] = SENSOR_RESOLUTION_WIDTH; //1600-8;
    gsSensorPreviewHeight[0] = SENSOR_RESOLUTION_HEIGHT; //1200-8;
    // use VGA for preview, check sensor preview setting
    gsSensorPreviewWidth[1] = SENSOR_RESOLUTION_WIDTH;//1600-8;
    gsSensorPreviewHeight[1] = SENSOR_RESOLUTION_HEIGHT;//1200-8;

#if (CUSTOMER == IPC) || (CUSTOMER == QDR) || (CUSTOMER == ANW)
    MMPF_PIO_EnableOutputMode(SEN_RST, MMP_TRUE);
    MMPF_PIO_EnableOutputMode(SEN_PWR_EN, MMP_TRUE);
    MMPF_PIO_EnableGpioMode(SEN_RST, MMP_TRUE);
    MMPF_PIO_EnableGpioMode(SEN_PWR_EN, MMP_TRUE);
    MMPF_PIO_EnableOutputMode(GPIO_SENSOR_PSEN,  MMP_TRUE);
    MMPF_PIO_EnableGpioMode(GPIO_SENSOR_PSEN, MMP_TRUE);
#endif

    if((gbDramID == MMPF_DRAMID_WINBOND_SDR16) || (gbDramID == MMPF_DRAMID_WINBOND_SDR16_1_8V)){
        GPIO_OutputControl(GPIO_SENSOR_PSEN, MMP_TRUE);
        MMPF_OS_Sleep_MS(5);
        //GPIO_OutputControl(GPIO_SENSOR_PSEN, MMP_FALSE);
    }
    else{
        MMPF_VIF_SetPIODir(VIF_SIF_SEN, MMP_TRUE);
        MMPF_VIF_SetPIOOutput(VIF_SIF_SEN, MMP_TRUE);  //Pin output high
        MMPF_OS_Sleep_MS(5);
        //MMPF_VIF_SetPIOOutput(VIF_SIF_SEN, MMP_FALSE);//Pin output low
    }

    GPIO_OutputControl(SEN_PWR_EN, TRUE);
    MMPF_OS_Sleep_MS(5);
    pVIF->VIF_SENSR_CLK_CTL[vif_id] = VIF_SENSR_CLK_EN;
    MMPF_OS_Sleep_MS(5);
    MMPF_VIF_SetPIOOutput(VIF_SIF_SEN, MMP_FALSE);//Pin output low
    MMPF_OS_Sleep_MS(5);

    /*Reset Sensor 500mS*/
#if (CUSTOMER == IPC) || (CUSTOMER == QDR) || (CUSTOMER == ANW)
    MMPF_PIO_SetData(SEN_RST, MMP_FALSE);
    MMPF_OS_Sleep_MS(5);
    MMPF_PIO_SetData(SEN_RST, MMP_TRUE);
    MMPF_OS_Sleep_MS(5);
//#else
    MMPF_VIF_SetPIODir(VIF_SIF_RST, MMP_TRUE);
    MMPF_VIF_SetPIOOutput(VIF_SIF_RST, MMP_FALSE);
    MMPF_OS_Sleep_MS(5);
    MMPF_VIF_SetPIOOutput(VIF_SIF_RST, MMP_TRUE);
    MMPF_OS_Sleep_MS(5);
#endif
    GPIO_OutputControl(GPIO_SENSOR_PSEN, MMP_FALSE);
    GPIO_OutputControl(SEN_PWR_EN, MMP_FALSE);
    
    SNR_GC0328_InitSensor_Customer();

    cur_res = GetResCfg(glPccamResolution);
    if(cur_res->res_w > gsSensorPreviewWidth[1] || cur_res->res_h > gsSensorPreviewHeight[1]) {
        gsSensorFunction->MMPF_Sensor_SetPreviewMode(0);
    }
    else{
        gsSensorFunction->MMPF_Sensor_SetPreviewMode(1);
    }

#if SUPPORT_AUTO_FOCUS
    MOTOR_GC0328_VCM_InitMotor_Customer();
#endif

#if SUPPORT_FLASH_LIGHT
    VR_Flash_Init();
#endif

    RTNA_DBG_Str(0, "MMPF_Sensor_Initialize_GC0328...End\r\n");
    return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_PowerDown_GC0328
//  Description :
//------------------------------------------------------------------------------

static MMP_ERR  MMPF_Sensor_PowerDown_GC0328(void)
{
    AITPS_VIF  pVIF = AITC_BASE_VIF;

    MMPF_VIF_EnableInputInterface(MMP_FALSE);

    if((gbDramID == MMPF_DRAMID_WINBOND_SDR16) || (gbDramID == MMPF_DRAMID_WINBOND_SDR16_1_8V)){
        GPIO_OutputControl(GPIO_SENSOR_PSEN, MMP_TRUE);
    }
    else{
        MMPF_VIF_SetPIODir(VIF_SIF_SEN, MMP_TRUE);
        MMPF_VIF_SetPIOOutput(VIF_SIF_SEN, MMP_TRUE);  //Pin output high
    }
    MMPF_OS_Sleep_MS(5);

    pVIF->VIF_SENSR_CLK_CTL[vif_id] &= (~ VIF_SENSR_CLK_EN) ;   //output sensor main clock


    #if (CUSTOMER == SNO)  
    GPIO_OutputControl(CAM_EN, FALSE);
    MMPF_OS_Sleep_MS(10);
    #endif
    #if (CUSTOMER == ANW)
    GPIO_OutputControl(SEN_PWR_EN, FALSE);
    #endif

    //MMPF_OS_Sleep_MS(20);

    RTNA_DBG_Str3( "MMPF_Sensor_PowerDown_GC0328() \r\n");
    return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_SetFrameRate_GC0328
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_SetFrameRate_GC0328(MMP_UBYTE ubFrameRate)
{
    return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_SetPreviewMode
//  Description :
//------------------------------------------------------------------------------

static MMP_ERR MMPF_Sensor_SetPreviewMode_GC0328(MMP_USHORT usPreviewmode)
{
    GC0328_Sensor_PreviewMode(usPreviewmode);

    return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_SetPreviewMode
//  Description :
//------------------------------------------------------------------------------

static MMP_ERR MMPF_Sensor_ChangePreviewMode_GC0328(
						MMP_USHORT usCurPreviewmode, MMP_USHORT usCurPhasecount,
						MMP_USHORT usNewPreviewmode, MMP_USHORT usNewPhasecount)
{
    GC0328_Sensor_PreviewMode(usNewPreviewmode);

    return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_ChangeMode
//  Description :
//------------------------------------------------------------------------------

/*static*/ MMP_ERR MMPF_Sensor_ChangeMode_GC0328(MMP_USHORT usPreviewmode, MMP_USHORT usCapturemode)
{
    switch (usPreviewmode) {
    case 0:
        switch (usCapturemode) {
        case 0:
            break;
        case 1:
            break;
        }
        break;
    case 1:
        switch (usCapturemode) {
        case 0:// SXGA preview, 5M capture
            MMPF_Sensor_SetPreviewMode_GC0328(0);
            // wait 3 frame ...
            // MMPF_Sensor_WaitFrame(5);
            break;
        case 1:
            MMPF_Sensor_SetPreviewMode_GC0328(1);
            // wait 3 frame ...
            //MMPF_Sensor_WaitFrame(3);

            break;
        }
        break;
    }

    return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_InitializeVIF
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_InitializeVIF_GC0328(void)
{
    AITPS_MIPI  pMIPI = AITC_BASE_MIPI;
    AITPS_VIF  pVIF = AITC_BASE_VIF;
    ISP_HDM_VIF_IF vif_if;
    MMP_ULONG   ulSENSORCLK;

    #if (SENSOR_IF == SENSOR_IF_PARALLEL)
    MMPF_VIF_RegisterInputInterface(MMPF_VIF_PARALLEL);
    pVIF->VIF_SENSR_CTL[vif_id] = VIF_SENSR_LATCH_PST | VIF_VSYNC_POLAR_NEG | VIF_14BPP_OUT_EN;
    #else
    pMIPI->MIPI_DATA0_DLY[vif_id] = 0x1000;  // set SOT counter to 0x10
    pMIPI->MIPI_DATA1_DLY[vif_id] = 0x1000;  // set SOT counter to 0x10

    MMPF_VIF_RegisterInputInterface(MMPF_VIF_MIPI);
    #endif

	// initialize VIF OPRs
#if (SENSOR_IF == SENSOR_IF_PARALLEL)
    vif_if = ISP_HDM_VIF_IF_PARALLEL;		//ISP_HDM_IF_InitVIF(ISP_HDM_VIF_IF_PARALLEL, 22);
#elif (SENSOR_IF == SENSOR_IF_MIPI_1_LANE)	
    vif_if = ISP_HDM_VIF_IF_MIPI_SINGLE_0;	//ISP_HDM_IF_InitVIF(ISP_HDM_VIF_IF_MIPI_SINGLE_0, 22);
#elif (SENSOR_IF == SENSOR_IF_MIPI_2_LANE)		
    vif_if = ISP_HDM_VIF_IF_MIPI_DUAL_01;	//ISP_HDM_IF_InitVIF(ISP_HDM_VIF_IF_MIPI_DUAL_01, 22);
#elif (SENSOR_IF == SENSOR_IF_MIPI_4_LANE)		
    vif_if = ISP_HDM_VIF_IF_MIPI_QUAD;		//ISP_HDM_IF_InitVIF(ISP_HDM_VIF_IF_MIPI_QUAD, 22);
#endif	

    {
        pVIF->VIF_INT_HOST_EN[vif_id] = 0;
        pVIF->VIF_INT_CPU_SR[vif_id] = VIF_INT_ALL;
        pVIF->VIF_OUT_EN[vif_id] = 0;
        pVIF->VIF_RAW_OUT_EN[vif_id] = 0;
        pVIF->VIF_FRME_SKIP_NO[vif_id] = 0;
        pVIF->VIF_FRME_SKIP_EN[vif_id] = 0;

        //RTNA_DBG_Str(0,"InitializeVIF\r\n");
        MMPF_PLL_GetGroupFreq(4, &ulSENSORCLK);

        switch(ulSENSORCLK){
            case 96000:
                pVIF->VIF_SENSR_CLK_FREQ[vif_id] = VIF_SENSR_CLK_PLL_D4; // 24MHz
                RTNA_DBG_Str3("96MHz DIV 4\r\n");
                break;
            case 144000:
                pVIF->VIF_SENSR_CLK_FREQ[vif_id] = VIF_SENSR_CLK_PLL_D6; 
                RTNA_DBG_Str3("144MHz DIV 6\r\n");
                break;
            case 192000:
                pVIF->VIF_SENSR_CLK_FREQ[vif_id] = VIF_SENSR_CLK_PLL_D8;
                RTNA_DBG_Str3("192MHz DIV 8\r\n");
                break;
            case 216000:
                pVIF->VIF_SENSR_CLK_FREQ[vif_id] = VIF_SENSR_CLK_PLL_D9;
                RTNA_DBG_Str3("216MHz DIV 9\r\n");
                break;
            case 240000:
                pVIF->VIF_SENSR_CLK_FREQ[vif_id] = VIF_SENSR_CLK_PLL_D10;
                RTNA_DBG_Str3("240MHz DIV 10\r\n");
                break;
            case 120000:
                pVIF->VIF_SENSR_CLK_FREQ[vif_id] = VIF_SENSR_CLK_PLL_D5;
                RTNA_DBG_Str3("120MHz DIV 5\r\n");
                break;
            default:
                pVIF->VIF_SENSR_CLK_FREQ[vif_id] = VIF_SENSR_CLK_PLL_D12;  // 144/12 = 12M
                break;
        }
#if NEW_SENSOR_SETTING
        pVIF->VIF_SENSR_CTL[vif_id] = VIF_SENSR_LATCH_PST | VIF_LINE_ID_POLAR | VIF_PIXL_ID_POLAR | VIF_VSYNC_POLAR_NEG;
        pVIF->VIF_YUV_CTL[vif_id] = /*VIF_YUV_FORMAT_YUV*/VIF_YUV_FORMAT_UVY | VIF_YUV_EN;
#else
	 pVIF->VIF_SENSR_CTL[vif_id] = VIF_SENSR_LATCH_PST | VIF_LINE_ID_POLAR | VIF_PIXL_ID_POLAR;
        pVIF->VIF_YUV_CTL[vif_id] = VIF_YUV_FORMAT_YUV | VIF_YUV_EN;
#endif        
	//pVIF->VIF_SENSR_CLK_CTL[vif_id] = VIF_SENSR_CLK_EN;   //Move to Sensor initialize
        pVIF->VIF_OPR_UPD[vif_id] = VIF_OPR_UPD_EN | VIF_OPR_UPD_FRAME;

        if (vif_if==ISP_HDM_VIF_IF_PARALLEL) {
            RTNA_DBG_Str0("ISP_HDM_VIF_IF_PARALLEL\r\n");
        }
        else {
            pMIPI->MIPI_DATA0_CFG[vif_id] = ((pMIPI->MIPI_DATA0_CFG[vif_id] & ~MIPI_DAT_SRC_SEL_MASK) | MIPI_DAT_SRC_PHY_1) | MIPI_CSI2_EN;
            if (vif_if == ISP_HDM_VIF_IF_MIPI_DUAL_01) {
                pMIPI->MIPI_DATA1_CFG[vif_id] = ((pMIPI->MIPI_DATA1_CFG[vif_id] & ~MIPI_DAT_SRC_SEL_MASK) | MIPI_DAT_SRC_PHY_2) | MIPI_CSI2_EN;
            }
            #if (CHIP == P_V2)
            else if(vif_if==ISP_HDM_VIF_IF_MIPI_QUAD){
                pMIPI->MIPI_DATA2_CFG = MIPI_CSI2_EN | MIPI_SRC_SEL_2;
                pMIPI->MIPI_DATA3_CFG = MIPI_CSI2_EN | MIPI_SRC_SEL_3;
                pMIPI->MIPI_DATA4_CFG = MIPI_CSI2_EN | MIPI_SRC_SEL_4;
            }
            #endif
        }
    }


    return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_InitializeISP
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_InitializeISP_GC0328(void)
{
    // register sensor (functions and variables)
    RTNA_DBG_Str(0, "ISP_IF_LIB_Init...\r\n");
    // check if ISP Lib and IQ are mismatched.
    ISP_IF_LIB_Init();
    // check if ISP Lib and IQ are mismatched.
    if (ISP_IF_LIB_CompareIQVer() != MMP_ERR_NONE) {
        RTNA_DBG_Str(0, "Wrong ISP lib version!\r\n");
        return MMP_ERR_NONE;
    }

    //RTNA_DBG_Str(0, "ISP_IF_3A_Init...S\r\n");
    // initialize 3A
    ISP_IF_3A_Init();

    // set AF type (ISP_AF_TYPE_ONE_SHOT / ISP_AF_TYPE_CONTINUOUS)
    ISP_IF_AF_SetType(ISP_AF_TYPE_CONTINUOUS);
    //RTNA_DBG_Str(0, "ISP_IF_3A_Init...E\r\n");

    //ISP_IF_AE_SetLowLuxMode(0);//disable Low light Compensation

    return  MMP_ERR_NONE;
}

//============================================================================

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_SetAFPosition_GC0328
//  Description :
// ---------------------------------------
static MMP_ERR MMPF_Sensor_SetAFPosition_GC0328(MMP_UBYTE ubPos)
{
#if SUPPORT_AUTO_FOCUS
    //if (gISPConfig.AutoFocusMode == VENUS_AF_MODE_MANUAL) {
        //gAFConfig.AFPos = ubPos;
        ISP_IF_AF_SetPos(ubPos, 8);
        MOTOR_GC0328_VCM_SetAFPosition_Customer(ISP_IF_AF_GetPos(0));
    //}

    //RTNA_DBG_Str(3, "  ubPos = ");       
    //RTNA_DBG_Short(3, ubPos);
    //RTNA_DBG_Str(3, "\r\n");
#endif
    return  MMP_ERR_NONE;
}
//ISP_UINT32 gISPFrameCnt;
#define MinFrameDivsor 5 // Gason@20120111, by OV suggestion, under 15 fps, dummy line will work every 5 frame.
#define FrameDivsor 4
ISP_UINT32 frame_div = 4;//9710  S&G delay 3 frame by grouphold 
static ISP_UINT32 gISPFrameCnt = 0;
//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_Do3AOperation
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_DoAWBOperation_GC0328(void)
{
    return MMP_ERR_NONE;
    switch (gISPFrameCnt % FrameDivsor){
    case 1:
        ISP_IF_AWB_Execute();
#ifndef ZDW_SET_EXPOSURE
        ISP_IF_IQ_SetAWBGains(ISP_IF_AWB_GetGainR(), ISP_IF_AWB_GetGainG(), ISP_IF_AWB_GetGainB(), ISP_IF_AWB_GetGainBase());
#endif
        break;
    case 2:		
        ISP_IF_CALI_Execute();
        break;
    }
    return  MMP_ERR_NONE;
}

//static ISP_UINT32  dgain,s_gain;
#define MAX_SENSOR_GAIN 16
#define ISP_DGAIN_BASE 0x200
//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_DoAEOperation_ST
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_DoAEOperation_ST_GC0328(void)
{
#ifdef ZDW_SET_EXPOSURE
    ISP_UINT32 s_gain, dgainbase=0x200;
    static ISP_UINT32 dgain;
    ISP_UINT32 H, L;
    ISP_UINT32 new_vsync, new_shutter;
    ISP_UINT32 ExtraVsyncWidth;

    if(ISP_IF_3A_GetSwitch(ISP_3A_ALGO_AE) != 1) return MMP_ERR_NONE;
    return MMP_ERR_NONE;
    switch (gISPFrameCnt % frame_div){
    case 0:
        ISP_IF_AE_Execute();

        //set sensor shutter
        new_vsync = g_SNR_LineCntPerSec * ISP_IF_AE_GetVsync() / ISP_IF_AE_GetVsyncBase();
        new_shutter = g_SNR_LineCntPerSec * ISP_IF_AE_GetShutter() / ISP_IF_AE_GetShutterBase();

        if (new_shutter <= ((g_SNR_LineCntPerSec / 15) - 5)) {
            ExtraVsyncWidth = 0;
        }
        else{
            ExtraVsyncWidth = (new_shutter + 5) - (g_SNR_LineCntPerSec / 15);	
            new_shutter     = ((g_SNR_LineCntPerSec / 15) - 5);
        }
        new_vsync       = (g_SNR_LineCntPerSec / 15);    //fix vsync

        //set sensor gain
        s_gain = ISP_MAX(ISP_IF_AE_GetGain(), ISP_IF_AE_GetGainBase());

        if (s_gain >= ISP_IF_AE_GetGainBase() * 16) {
            dgain = s_gain * dgainbase / (ISP_IF_AE_GetGainBase() * 16);
            s_gain = ISP_IF_AE_GetGainBase() * 16;
        } else {
            dgain  = dgainbase;
        }

        if (s_gain >= ISP_IF_AE_GetGainBase() * 16) {
            H = 15;
            s_gain /= 16;
        }else if (s_gain >= ISP_IF_AE_GetGainBase() * 8) {
            H = 7;
            s_gain /= 8;
        } else if (s_gain >= ISP_IF_AE_GetGainBase() * 4) {
            H = 3;
            s_gain /= 4;
        } else if (s_gain >= ISP_IF_AE_GetGainBase() * 2) {
            H = 1;
            s_gain /= 2;
        } else {
            H = 0;
        }

        L = s_gain * 16 / ISP_IF_AE_GetGainBase() - 16;
			
        if (L > 15) L = 15;
			
        //GC0328 gain nonlinear at following point / 20140225 JS
        if ( (H<<4)+L == 0x10 || (H<<4)+L == 0x30 || (H<<4)+L == 0x70 )
            L = 1;

        //new_s_gain = (L + 16) * ISP_IF_AE_GetGainBase() / 16;
        dgain = s_gain * dgainbase / ((L + 16) * ISP_IF_AE_GetGainBase() / 16);
#if 0
        // set sensor gain
        gsSensorFunction->MMPF_Sensor_SetReg(0x00, (H<<4)+L);

        // set sensor shutter & vsync		
        gsSensorFunction->MMPF_Sensor_SetReg(0x3E, new_vsync >> 8);
        gsSensorFunction->MMPF_Sensor_SetReg(0x3D, new_vsync);

        gsSensorFunction->MMPF_Sensor_SetReg(0x16, new_shutter >> 8);
        gsSensorFunction->MMPF_Sensor_SetReg(0x10, new_shutter);

        gsSensorFunction->MMPF_Sensor_SetReg(0x2E, ExtraVsyncWidth >> 8);
        gsSensorFunction->MMPF_Sensor_SetReg(0x2D, ExtraVsyncWidth);
#endif
        break;
    case 1:
        //ISP_IF_IQ_SetAEGain(dgain, dgainbase);
        break;
    }
#endif
    return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_DoAEOperation_END
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_DoAEOperation_END_GC0328(void)
{
    return MMP_ERR_NONE;
#ifdef ZDW_SET_EXPOSURE
    gISPFrameCnt++;
    if(ISP_IF_3A_GetSwitch(ISP_3A_ALGO_AE) != 1) return MMP_ERR_NONE;

    switch (gISPFrameCnt % frame_div){
    case 1:
        ISP_IF_AWB_GetHWAcc(1);
        break;
    case 3:
        ISP_IF_AE_GetHWAcc(1);
#if (MotionDetection == 1)
        COLOR_StoreAEAcc();
#endif
        break;
    }
#endif
    return  MMP_ERR_NONE;
}


//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_DoAFOperation
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_DoAFOperation_GC0328(void)
{
#if SUPPORT_AUTO_FOCUS
    if(gbAutoFocus == MMP_TRUE){
        //VR_AF_GetAcc();
        ISP_IF_AF_GetHWAcc(1);
        //ISP_IF_R_DoAF();
    }
#endif

    return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_DoAFOperation
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_DoAFOperation_FrameStart_GC0328(void)
{
#if SUPPORT_AUTO_FOCUS
    if(gbAutoFocus == MMP_TRUE){
        //VR_AF_GetAcc();
        //ISP_IF_R_GetAFAcc();
        //ISP_IF_R_DoAF();
        {
            static ISP_UINT32 frame_cnt = 0;

            switch (frame_cnt++ % 1) {
            case 0:
                ISP_IF_AF_Execute();
                MOTOR_GC0328_VCM_SetAFPosition_Customer(ISP_IF_AF_GetPos(0));
                break;
            }
        }
    }
#endif

    return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_DoIQOperation_GC0328
//  Description :
//------------------------------------------------------------------------------
//extern MMP_UBYTE gbSkypeMode;
extern H264_FORMAT_TYPE gbCurH264Type;
static MMP_ERR  MMPF_Sensor_DoIQOperation_GC0328(void)
{
    // switch IQ table if video format is H264
    //PCAM_USB_VIDEO_FORMAT vidFmt = pcam_get_info()->pCamVideoFormat;

    switch (gISPFrameCnt % 2) {
    case 0:
        break;

    case 1:
        // set iq (NR, Edge, CCM, Gamma, etc.) and functions (saturation, contrast, sharpness, hue, etc.)
        ISP_IF_IQ_SetAll();
        ISP_IF_IQ_CheckBypass();

        MMPF_SetPrivacyMask(en_flag, privacymask);
        break;
    }
    return  MMP_ERR_NONE;
}

// Steven ADD
//------------------------------------------------------------------------------
//  Function    : MMPF_SetLightFreq
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_SetLightFreq_GC0328(MMP_USHORT usMode)
{
#if 0

    RTNA_DBG_Str(0, "MMPF_SetLightFreq_GC0328 : ");
    RTNA_DBG_Short(0, usMode);
    RTNA_DBG_Str(0, "\r\n");

    /*
    typedef enum {
        VENUS_FLICKER_MODE_OFF              = 0,
        VENUS_FLICKER_MODE_AUTO             = 1,
        VENUS_FLICKER_MODE_60HZ             = 2,
        VENUS_FLICKER_MODE_50HZ             = 3,
        VENUS_FLICKER_MODE_CAL_BASESHUTTER  = 4
    } VENUS_FLICKER_MODE;
    */

    switch(usMode) {
    case 0:
    case 2:
        //gISPConfig.FlickerMode = VENUS_FLICKER_MODE_60HZ;
        ISP_IF_AE_SetFlicker(ISP_AE_FLICKER_60HZ);
        break;
    case 1:
    case 3:
        //gISPConfig.FlickerMode = VENUS_FLICKER_MODE_50HZ;
        ISP_IF_AE_SetFlicker(ISP_AE_FLICKER_50HZ);
        break;
    default:
        //gISPConfig.FlickerMode = VENUS_FLICKER_MODE_AUTO;
        ISP_IF_AE_SetFlicker(ISP_AE_FLICKER_AUTO);
    }
#endif

    return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_SetStableState_GC0328(MMP_BOOL bStableState)
{
    return  MMP_ERR_NONE;
}

MMP_ERR MMPF_SetHistEQState_GC0328(MMP_BOOL bHistEQState)
{

    return  MMP_ERR_NONE;
}

extern volatile MMP_UBYTE gbDramID;
static MMP_ERR  MMPF_Sensor_SetReg_GC0328(MMP_USHORT usAddr, MMP_USHORT usData)
{
    if((gbDramID == MMPF_DRAMID_WINBOND_SDR16) || (gbDramID == MMPF_DRAMID_WINBOND_SDR16_1_8V)){
    //    m_snr_I2cmAttribute.uI2cmID = MMPF_I2CM_ID_0;  // for AIT8433 70 pin package
    }
    else{
    //    m_snr_I2cmAttribute.uI2cmID = MMPF_I2CM_ID_1;  // for AIT8451 105 pin package
    }
    MMPF_I2cm_WriteReg(&m_snr_I2cmAttribute, usAddr, usData);
    return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_GetReg_GC0328(MMP_USHORT usAddr, MMP_USHORT *usData)
{
    *usData = 0xFF;
    if((gbDramID == MMPF_DRAMID_WINBOND_SDR16) || (gbDramID == MMPF_DRAMID_WINBOND_SDR16_1_8V)){
    //    m_snr_I2cmAttribute.uI2cmID = MMPF_I2CM_ID_0;  // for AIT8433 70 pin package
    }
    else{
    //    m_snr_I2cmAttribute.uI2cmID = MMPF_I2CM_ID_1;  // for AIT8451 105 pin package
    }
    MMPF_I2cm_ReadReg(&m_snr_I2cmAttribute, usAddr, usData);

    return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_SetImageScene_GC0328(MMP_USHORT imgSceneID)
{
#if 0
/*
typedef enum {
    ISP_SCENE_AUTO					= 0,	// scene mode
    ISP_SCENE_PORTRAIT				= 1,	// scene mode
    ISP_SCENE_LANDSCAPE				= 2,	// scene mode
    ISP_SCENE_SPORTS				= 3,	// scene mode
    ISP_SCENE_SUNSET				= 4,	// scene mode
    ISP_SCENE_DUSK					= 5,	// scene mode
    ISP_SCENE_DAWN					= 6,	// scene mode
    ISP_SCENE_NIGHT_SHOT			= 7,	// scene mode
    ISP_SCENE_AGAINST_LIGHT			= 8,	// scene mode
    ISP_SCENE_TEXT					= 9,	// scene mode
    ISP_SCENE_MANUAL				= 10,	// scene mode
    ISP_SCENE_INDOOR				= 11,	// scene mode
    ISP_SCENE_SNOW					= 12,	// scene mode
    ISP_SCENE_FALL					= 13,	// scene mode
    ISP_SCENE_WAVE					= 14,	// scene mode
    ISP_SCENE_FIREWORKS				= 15,	// scene mode
    ISP_SCENE_SHOW_WIN				= 16,	// scene mode
    ISP_SCENE_CANDLE				= 17,	// scene mode
    ISP_SCENE_NONE					= 18	// camera mode
} ISP_SCENE;
*/
    imgSceneID = (imgSceneID % (ISP_SCENE_NONE+1));

    RTNA_DBG_Str(3, "MMPF_SetImageScene_GC0328 : ");
    RTNA_DBG_Byte(3, imgSceneID);
    RTNA_DBG_Str(3, "\r\n");

    //if (g3AConfig.Control3A == ISP_3A_ENABLE)
        MMPF_Sensor_CheckFrameEnd(1);
    ISP_IF_F_SetScene(imgSceneID);
#endif

    return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_SetAEMode_GC0328(MMP_UBYTE ubAEMode, MMP_UBYTE ubISOMode)
{
#if 0
/*
typedef enum {
    AE_MODE_AUTO						= 0,
    AE_MODE_MANUAL						= 1,
    AE_MODE_ISO							= 2,
    AE_MODE_SHUTTER						= 3
} VENUS_AE_MODE;
*/
/*
typedef enum {
    AE_ISO_AUTO					= 0,
    AE_ISO_50					= 1,
    AE_ISO_100					= 2,
    AE_ISO_200					= 3,
    AE_ISO_400					= 4,
    AE_ISO_800					= 5,
    AE_ISO_1600					= 6,
    AE_ISO_3200					= 7,
    ISP_AE_ISO_NUM
} VENUS_AE_ISO;
*/
    #if 0 //FIXME, VSN_V2
    if (ubAEMode == 3)
        ISP_IF_AE_SetISO(ISP_AE_MODE_AUTO);
    else
    #endif
        ISP_IF_AE_SetISO(ubISOMode);
#endif
	
    return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_SetAFMode_GC0328(MMP_UBYTE ubAFMode)
{
#if 0
/*
typedef enum {
    VENUS_AF_MODE_AUTO					= 0,
    VENUS_AF_MODE_MANUAL				= 1,
    VENUS_AF_MODE_MACRO					= 2,
    VENUS_AF_MODE_FULL					= 3,
    VENUS_AF_MODE_MOTOR_TEST            = 4,
    VENUS_AF_MODE_NULL					= 5
} VENUS_AF_MODE;
*/
    RTNA_DBG_Str(3, "MMPF_Sensor_SetAFMode_GC0328 : ");
    RTNA_DBG_Byte(3, ubAFMode);
    RTNA_DBG_Str(3, "\r\n");

    //gISPConfig.AutoFocusMode = (MMP_UBYTE)ubAFMode;
    //if (g3AConfig.Control3A == ISP_3A_ENABLE)
    //	MMPF_Sensor_CheckFrameEnd(1);
    ISP_IF_AF_SetMode(ubAFMode);
#endif

    return  MMP_ERR_NONE;
}

//======================================================================//
// function : MMPF_Sensor_SetImageEffect                                //
// parameters:                                                          //
// return :                                                             //
// description :                                                        //
//======================================================================//
static MMP_ERR  MMPF_Sensor_SetImageEffect_GC0328(MMP_USHORT imgEffectID)
{
#if 0
/*
typedef enum {
    ISP_IMAGE_EFFECT_NORMAL			= 0,
    ISP_IMAGE_EFFECT_GREY			= 1,
    ISP_IMAGE_EFFECT_SEPIA			= 2,
    ISP_IMAGE_EFFECT_NEGATIVE		= 3,
    ISP_IMAGE_EFFECT_ANTIQUE		= 4,
    ISP_IMAGE_EFFECT_WATERCOLOR		= 5,
    ISP_IMAGE_EFFECT_PORTRAIT		= 6,
    ISP_IMAGE_EFFECT_LANDSCAPE		= 7,
    ISP_IMAGE_EFFECT_SUNSET			= 8,
    ISP_IMAGE_EFFECT_DUSK			= 9,
    ISP_IMAGE_EFFECT_DAWN			= 10,
    ISP_IMAGE_EFFECT_RED			= 11,
    ISP_IMAGE_EFFECT_GREEN			= 12,
    ISP_IMAGE_EFFECT_BLUE			= 13,
    ISP_IMAGE_EFFECT_YELLOW			= 15,
    ISP_IMAGE_EFFECT_EMBOSS			= 17,
    ISP_IMAGE_EFFECT_OIL			= 18,
    ISP_IMAGE_EFFECT_BW				= 19,
    ISP_IMAGE_EFFECT_SKETCH			= 20,
    ISP_IMAGE_EFFECT_CRAYONE		= 21,
    ISP_IMAGE_EFFECT_WHITEBOARD		= 22,
    ISP_IMAGE_EFFECT_BLACKBOARD		= 23,
    ISP_IMAGE_EFFECT_VIVID			= 24,
    ISP_IMAGE_EFFECT_NUM
} ISP_IMAGE_EFFECT;
*/

    imgEffectID = (imgEffectID % (ISP_IMAGE_EFFECT_NUM+1));

    RTNA_DBG_Str(3, "MMPF_Sensor_SetImageEffect_GC0328 : ");
    RTNA_DBG_Byte(3, imgEffectID);
    RTNA_DBG_Str(3, "\r\n");

    //gISPConfig.ImageEffect = (MMP_USHORT)imgEffectID;
    //if (g3AConfig.Control3A == ISP_3A_ENABLE)
    //	MMPF_Sensor_CheckFrameEnd(1);
    ISP_IF_F_SetImageEffect(imgEffectID);
#endif

    return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_SetAWBType_GC0328(MMP_UBYTE ubType)
{
#if 0
    RTNA_DBG_Str(3, "MMPF_Sensor_SetAWBType_GC0328 : ");
    RTNA_DBG_Byte(3, ubType);
    RTNA_DBG_Str(3, "\r\n");

    cAWBtype = ubType;
#endif
    return  MMP_ERR_NONE;
}
static MMP_ERR  MMPF_Sensor_SetContrast_GC0328(MMP_SHORT ubLevel)
{
#if 0
    RTNA_DBG_Str(3, "MMPF_Sensor_Contrast_GC0328 : ");
    RTNA_DBG_Byte(3, ubLevel);
    RTNA_DBG_Str(3, "\r\n");

    //gISPConfig.ContrastLevel = ubLevel;
    ISP_IF_F_SetContrast(ubLevel);
#endif

    return  MMP_ERR_NONE;
}
static MMP_ERR  MMPF_Sensor_SetSaturation_GC0328(MMP_SHORT ubLevel)
{
#if 0
    RTNA_DBG_Str(3, "MMPF_Sensor_SetSaturation_GC0328 : ");
    RTNA_DBG_Byte(3, ubLevel);
    RTNA_DBG_Str(3, "\r\n");

    //gISPConfig.SaturationLevel = ubLevel;
    ISP_IF_F_SetSaturation(ubLevel);
#endif

    return  MMP_ERR_NONE;
}
static MMP_ERR  MMPF_Sensor_SetSharpness_GC0328(MMP_SHORT ubLevel)
{
#if 0
    RTNA_DBG_Str(3, "MMPF_Sensor_SetSharpness_GC0328 : ");
    RTNA_DBG_Byte(3, ubLevel);
    RTNA_DBG_Str(3, "\r\n");

    //gISPConfig.SharpnessLevel = ubLevel;
    ISP_IF_F_SetSharpness(ubLevel);
#endif

    return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_SetHue_GC0328(MMP_SHORT ubLevel)
{
#if 0
    RTNA_DBG_Str(3, "MMPF_Sensor_SetHue_GC0328 : ");
    RTNA_DBG_Byte(3, ubLevel);
    RTNA_DBG_Str(3, "\r\n");

    ISP_IF_F_SetHue(ubLevel);
#endif

    return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_SetGamma_GC0328(MMP_SHORT ubLevel)
{
#if 0
    RTNA_DBG_Str(3, "MMPF_Sensor_SetGamma_GC0328 : ");
    RTNA_DBG_Byte(3, ubLevel);
    RTNA_DBG_Str(3, "\r\n");

    ISP_IF_F_SetGamma(ubLevel);
#endif

    return  MMP_ERR_NONE;
}

/*static MMP_ERR  MMPF_Sensor_SetBacklight_GC0328(MMP_UBYTE ubLevel)
{
#if 0
    RTNA_DBG_Str(3, "MMPF_Sensor_SetBacklight_GC0328 : ");
    RTNA_DBG_Byte(3, ubLevel);
    RTNA_DBG_Str(3, "\r\n");

    //ISP_IF_F_SetBacklight(ubLevel);
    if(ubLevel > 1){
        ISP_IF_F_SetWDR(ISP_WDR_DISABLE);
    }
    else{
        ISP_IF_F_SetWDR(ISP_WDR_ENABLE);
    }
#endif

    return  MMP_ERR_NONE;
}

*/

static void  MMPF_Sensor_SetCaptureISPSetting_GC0328(MMP_UBYTE usCaptureBegin)
{
#if 0
    AITPS_VIF   pVIF = AITC_BASE_VIF;
    MMP_ULONG   ulVIF_Width, ulVIF_Height;
    //MMP_UBYTE   vif_id = 0;

    /* ToDo: setting IOS and ISP windows*/
    if(MMP_TRUE == usCaptureBegin){
        ulVIF_Width = (pVIF->VIF_GRAB[vif_id].PIXL_ED - pVIF->VIF_GRAB[vif_id].PIXL_ST + 1);
        ulVIF_Height = (pVIF->VIF_GRAB[vif_id].LINE_ED - pVIF->VIF_GRAB[vif_id].LINE_ST + 1);
        //gSensorFunc.SetISPWindows(ulVIF_Width,ulVIF_Height);
    }
#endif
	
    return;
}

/*Prepare for raw preview zoom*/
static void  MMPF_Sensor_SetISPWindow_GC0328(MMP_ULONG ulWidth, MMP_ULONG ulHeight)
{
    //gSensorFunc.SetISPWindows(ulWidth,ulHeight);
    return;
}

/*Check AIT can preview in this resolution*/
static MMP_UBYTE  MMPF_Sensor_CheckPreviewAbility_GC0328(MMP_USHORT usPreviewmode)
{
#if 0
    switch(usPreviewmode){
        case 0:                 //5M can't preview
            return MMP_TRUE;
            break;
        case 1:                 //1.3M can preview
            return MMP_TRUE;
            break;
    }
#endif
	
    return MMP_TRUE;            //5M and 1.3M always can preview
}

static void SetAFWin_GC0328(MMP_USHORT usIndex, MMP_USHORT usPreviewWidth, MMP_USHORT usPreviewHeight,
					MMP_USHORT  usStartX, MMP_USHORT  usStartY, MMP_USHORT  usWidth, MMP_USHORT  usHeight)
{

    //DBG_S3("SetAFWin (TODO)\r\n");
}

//static MMP_BOOL VGAPreview = MMP_TRUE;
static void SetAFEnable_GC0328(MMP_UBYTE enable)
{
    //if (enable) {
        //RTNA_DBG_Str(3, "VENUS_ISP_AUTO_FOCUS_STATUS_START\r\n");
        ISP_IF_AF_Control(ISP_AF_START);
        //actually calling SNR_GC0328_SetAutoFocusControl()
    //} else {
        //RTNA_DBG_Str(3, "VENUS_ISP_AUTO_FOCUS_STATUS_STOP\r\n");
        //ISP_IF_AF_Control(ISP_AF_STOP);
    //}
}

static MMP_ERR MMPF_Sensor_SetAEEnable_GC0328(MMP_UBYTE bEnable)
{
    /*
    if (bEnable) {
        g3AConfig.AE_Enabled     = ON;
    }
    else {
        g3AConfig.AE_Enabled     = OFF;
    }*/

    ISP_IF_3A_SetSwitch(ISP_3A_ALGO_AE, bEnable);

    return MMP_ERR_NONE;
}

static MMP_ERR MMPF_Sensor_SetAWBEnable_GC0328(MMP_UBYTE bEnable)
{
#if 0
    if (bEnable) {
        g3AConfig.AWB_Enabled    = ON;
        g3AConfig.AWBRGB_Enabled = ON;
    }
    else {
        g3AConfig.AWB_Enabled    = OFF;
        g3AConfig.AWBRGB_Enabled = OFF;
    }
#endif

    if(bEnable)
        ISP_IF_AWB_SetMode(ISP_AWB_MODE_AUTO);
    else
        ISP_IF_AWB_SetMode(ISP_AWB_MODE_MANUAL);

    return MMP_ERR_NONE;
}
static void SetAEsmooth_GC0328(MMP_UBYTE smooth)  {return;}
static MMP_ERR MMPF_Sensor_SetExposureValue_GC0328(MMP_UBYTE ev)
{
#if 0
    RTNA_DBG_Str(3, "MMPF_Sensor_SetExposureValue_GC0328 : ");
    //RTNA_DBG_Byte(3, gISPConfig.EV);
    //RTNA_DBG_Str(3, " : ");
    RTNA_DBG_Byte(3, ev);
    RTNA_DBG_Str(3, "\r\n");

    ISP_IF_AE_SetEV(ev);
#endif

    return MMP_ERR_NONE;
}

static MMP_UBYTE GetAFPosition_GC0328     (void){ return 0;/*volatile MMP_UBYTE *GPIO_BASE_B = (volatile MMP_UBYTE *)0x80009400;  return GPIO_BASE_B[0xB0];*/}


static MMP_UBYTE GetAFEnable_GC0328(void)
{
    //return 0;
    return ISP_IF_AF_GetResult();
}

static MMP_UBYTE GetExposureValue_GC0328  (void){return ISP_IF_AE_GetEV();}
static MMP_UBYTE GetAEsmooth_GC0328       (void){return 0;}
//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_Set3AStatus
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR	MMPF_Sensor_Set3AStatus_GC0328(MMP_BOOL bEnable)
{
    #if 1
    MMPF_Sensor_3A_SetInterrupt(bEnable);
    //#else
    if (bEnable)
        ISP_IF_3A_Control(ISP_3A_ENABLE);
    else
        ISP_IF_3A_Control(ISP_3A_DISABLE);
    #endif
    return	MMP_ERR_NONE;
}

static void  MMPF_Sensor_SetColorID_GC0328(MMPF_SENSOR_ROTATE_TYPE RotateType)
{	    
    //ISP_IF_3A_Control(ISP_3A_PAUSE);
    
    switch(RotateType) {
    case MMPF_SENSOR_ROTATE_NO_ROTATE:
        gsSensorFunction->MMPF_Sensor_SetReg(0x17,0x00);
        ISP_IF_IQ_SetColorID(0);
        break;
    case MMPF_SENSOR_ROTATE_RIGHT_90:
        break;
    case MMPF_SENSOR_ROTATE_RIGHT_180:
        gsSensorFunction->MMPF_Sensor_SetReg(0x17,0x03);
        ISP_IF_IQ_SetColorID(3);
        break;
    case MMPF_SENSOR_ROTATE_RIGHT_270:
        break;
    case MMPF_SENSOR_ROTATE_H_MIRROR:
        gsSensorFunction->MMPF_Sensor_SetReg(0x17,0x01);
        ISP_IF_IQ_SetColorID(1);
        break;
    case MMPF_SENSOR_ROTATE_V_FLIP:
        gsSensorFunction->MMPF_Sensor_SetReg(0x17,0x02);
        ISP_IF_IQ_SetColorID(2);
        break;
    }
    ISP_IF_IQ_SetDirection((ISP_UINT8)RotateType);
    //ISP_IF_3A_Control(ISP_3A_RECOVER);
    return;
}

static void MMPF_Sensor_SetSensorGain_GC0328(MMP_ULONG gain)
{
    MMP_USHORT s_gain;
    MMP_ULONG  H, L;

    s_gain = VR_MIN(VR_MAX(gain, 64), 511); // API input gain range : 64~511, 64=1X
return;
    if (s_gain >= 64 * 8) {
        H = 7;
    } else if (s_gain >= 64 * 4) {
        H = 3;
    } else if (s_gain >= 64 * 2) {
        H = 1;
    } else {
        H = 0;
    }

    L = s_gain * 16 / 64 / (H+1) - 16;

    if (L > 15) L = 15;	

    // set sensor gain
    MMPF_Sensor_SetReg_GC0328(0xB0, (H<<4)+L);

}

void MMPF_Sensor_SetSensorShutter_GC0328K(MMP_ULONG dir, MMP_ULONG vsync)
{
	MMP_USHORT value = 0x08;
	MMP_USHORT shut[4] = {0x04, 0x08, 0x0c,0x12};
	int oldShut;
	int  newShut;

    return;
	MMPF_Sensor_GetReg_GC0328(0x03,&value);

	for(oldShut = 0 ; oldShut < 4 ; oldShut++)
	{
		if(shut[oldShut] == value)
			break;
	}

	if(dir == 2){
		if(oldShut > 0)
			newShut = --oldShut;
		else
			return;
	}else if(dir == 1){
		if(oldShut<3)
			newShut = ++oldShut;
		else
			return;
	}

	MMPF_Sensor_SetReg_GC0328(0x03, shut[newShut]);

}

static void MMPF_Sensor_SetSensorShutter_GC0328(MMP_ULONG dir, MMP_ULONG vsync)
{
/*    //ISP_UINT32 new_vsync = g_SNR_LineCntPerSec * ISP_IF_AE_GetVsync() / ISP_IF_AE_GetVsyncBase();
    ISP_UINT32 new_shutter = g_SNR_LineCntPerSec * ISP_IF_AE_GetShutter() / ISP_IF_AE_GetShutterBase();

    //new_vsync   = VR_MAX(vsync, shutter + 5);  //+8
    new_shutter = 1;//VR_MIN(VR_MAX(shutter, 1), new_vsync - 2);//2);

    //MMPF_Sensor_SetReg_GC0328(0x43, new_vsync >> 8);
    //MMPF_Sensor_SetReg_GC0328(0x42, new_vsync);

    MMPF_Sensor_SetReg_GC0328(0x03, new_shutter >> 8);
    MMPF_Sensor_SetReg_GC0328(0x04, new_shutter);
    //Exposure[13:8]:0x03[5:0]  Exposure[7:0]:0x04
*/
	MMP_USHORT value = 0x08;
	MMP_USHORT shut[4] = {0x04, 0x08, 0x0c,0x12};
	int oldShut;
	int  newShut;

    return;
	MMPF_Sensor_GetReg_GC0328(0x03,&value);

	for(oldShut = 0 ; oldShut < 4 ; oldShut++)
	{
		if(shut[oldShut] == value)
			break;
	}

	if(dir == 2){
		if(oldShut > 0)
			newShut = --oldShut;
		else
			return;
	}else if(dir == 1){
		if(oldShut<3)
			newShut = ++oldShut;
		else
			return;
	}

	MMPF_Sensor_SetReg_GC0328(0x03, shut[newShut]);
}

MMPF_SENSOR_FUNCTION  SensorFunction_GC0328 =
{
    MMPF_Sensor_Initialize_GC0328,
    MMPF_Sensor_InitializeVIF_GC0328,
    MMPF_Sensor_InitializeISP_GC0328,
    MMPF_Sensor_PowerDown_GC0328,
    MMPF_Sensor_SetFrameRate_GC0328,
    MMPF_Sensor_ChangeMode_GC0328,
    MMPF_Sensor_ChangePreviewMode_GC0328,
    MMPF_Sensor_SetPreviewMode_GC0328,
    MMPF_Sensor_SetReg_GC0328,
    MMPF_Sensor_GetReg_GC0328,
    MMPF_Sensor_DoAWBOperation_GC0328,
    MMPF_Sensor_DoAEOperation_ST_GC0328,
    MMPF_Sensor_DoAEOperation_END_GC0328,
    MMPF_Sensor_DoAFOperation_GC0328,
    MMPF_Sensor_DoAFOperation_FrameStart_GC0328,
    MMPF_Sensor_DoIQOperation_GC0328,
    MMPF_Sensor_SetImageEffect_GC0328,
    MMPF_SetLightFreq_GC0328,
    MMPF_SetStableState_GC0328,
    MMPF_SetHistEQState_GC0328,
    MMPF_Sensor_SetAFPosition_GC0328,
    SetAFWin_GC0328,
    SetAFEnable_GC0328,
    MMPF_Sensor_SetAEEnable_GC0328,
    MMPF_Sensor_SetAWBEnable_GC0328,
    MMPF_Sensor_SetExposureValue_GC0328,
    SetAEsmooth_GC0328,
    MMPF_Sensor_SetImageScene_GC0328,
    GetAFPosition_GC0328,
    GetAFEnable_GC0328,
    GetExposureValue_GC0328,
    GetAEsmooth_GC0328,
    MMPF_Sensor_SetAWBType_GC0328,
    MMPF_Sensor_SetContrast_GC0328,
    MMPF_Sensor_SetSaturation_GC0328,
    MMPF_Sensor_SetSharpness_GC0328,
    MMPF_Sensor_SetHue_GC0328,
    MMPF_Sensor_SetGamma_GC0328,
    //MMPF_Sensor_SetBacklight_GC0328,
    MMPF_Sensor_SetAEMode_GC0328,
    MMPF_Sensor_SetAFMode_GC0328,
    MMPF_Sensor_SetCaptureISPSetting_GC0328,
    MMPF_Sensor_SetISPWindow_GC0328,
    MMPF_Sensor_CheckPreviewAbility_GC0328,
    MMPF_Sensor_Set3AStatus_GC0328,
    MMPF_Sensor_SetColorID_GC0328,
    MMPF_Sensor_SetSensorGain_GC0328,
    MMPF_Sensor_SetSensorShutter_GC0328
};

#define SLAVE_ID 1
#define sccb_write(a,b,c) b,c
                                 
#if NEW_SENSOR_SETTING
MMP_USHORT SNR_GC0328_Reg_Init_Customer[] =
{

 //0xfe, 0x80, // [7]: soft_reset, [1:0] page select
 //0xfe, 0x00, // [7]: soft_reset, [1:0] page select

sccb_write(SLAVE_ID,0xfe , 0x80),
sccb_write(SLAVE_ID,0xfc , 0x16),
sccb_write(SLAVE_ID,0xfc , 0x16),
sccb_write(SLAVE_ID,0xfc , 0x16),
sccb_write(SLAVE_ID,0xfc , 0x16),
sccb_write(SLAVE_ID,0xf1 , 0x00),
sccb_write(SLAVE_ID,0xf2 , 0x00),
sccb_write(SLAVE_ID,0xfe , 0x00),
sccb_write(SLAVE_ID,0x4f , 0x00),
sccb_write(SLAVE_ID,0x03 , 0x00),
sccb_write(SLAVE_ID,0x04 , 0xc0),
sccb_write(SLAVE_ID,0x42 , 0x00),
sccb_write(SLAVE_ID,0x77 , 0x5a),
sccb_write(SLAVE_ID,0x78 , 0x40),
sccb_write(SLAVE_ID,0x79 , 0x56),
sccb_write(SLAVE_ID,0xfe , 0x00),
//===========================
sccb_write(SLAVE_ID,0x0d , 0x01), // 488
sccb_write(SLAVE_ID,0x0e , 0xe8),
sccb_write(SLAVE_ID,0x0f , 0x02),  // 648
sccb_write(SLAVE_ID,0x10 , 0x88),
//sccb_write(SLAVE_ID,0x0d , 0x00),  // 248
//sccb_write(SLAVE_ID,0x0e , 0xf8),
//sccb_write(SLAVE_ID,0x0f , 0x01),  // 328
//sccb_write(SLAVE_ID,0x10 , 0x48),
//===========================
sccb_write(SLAVE_ID,0x09 , 0x00),
sccb_write(SLAVE_ID,0x0a , 0x00),
sccb_write(SLAVE_ID,0x0b , 0x00),
sccb_write(SLAVE_ID,0x0c , 0x00),
//sccb_write(SLAVE_ID,0x50 , 0x00), // test

sccb_write(SLAVE_ID,0x16 , 0x00),
sccb_write(SLAVE_ID,0x17 , 0x14),
sccb_write(SLAVE_ID,0x18 , 0x0e),
sccb_write(SLAVE_ID,0x19 , 0x06),
sccb_write(SLAVE_ID,0x1b , 0x48),
sccb_write(SLAVE_ID,0x1f , 0xC8),
sccb_write(SLAVE_ID,0x20 , 0x01),
sccb_write(SLAVE_ID,0x21 , 0x78),
sccb_write(SLAVE_ID,0x22 , 0xb0),
sccb_write(SLAVE_ID,0x23 , 0x04),//0x06  20140519 GC0328C
sccb_write(SLAVE_ID,0x24 , 0x11),
sccb_write(SLAVE_ID,0x26 , 0x00),

//sccb_write(SLAVE_ID,0x50 , 0x01),//crop mode

#if (SENSOR_OUTPUT == 1)    
//0x5a, 0x0e, 
0x59, 0x22, // subsample ratio, 0x11/0x22/0x33....
0x5b, 0x00, 
0x5c, 0x00, 
0x5d, 0x00,
0x5f, 0x00,
0x60, 0x00, 
0x61, 0x00, 
0x62, 0x00, 
#elif (SENSOR_OUTPUT == 2)    
//0x5a, 0x0e, 
0x59, 0x44, // subsample ratio, 0x11/0x22/0x33....
0x5b, 0x00, 
0x5c, 0x00, 
0x5d, 0x00,
0x5f, 0x00,
0x60, 0x00, 
0x61, 0x00, 
0x62, 0x00, 
#elif (SENSOR_OUTPUT == 3)    
/////crop window///////
0x50, 0x01, // [0]: crop window mode enable
0x51, 0x00,
0x52, 0x00,
0x53, 0x00,
0x54, 0x00,
0x55, 0x01, //320
0x56, 0x40,
0x57, 0x01, //320
0x58, 0x40,
////////measure Window///////
0xfe, 0x01,
0x06, 0x08,
0x07, 0x06,
0x08, 0x58,
0x09, 0xa0,
0x0a, 0x1b,
0x0b, 0x1b,
0x0c, 0x36,
0x0d, 0x36,
0xfe, 0x00,
#elif (SENSOR_OUTPUT == 4)    
/////crop window///////
0x50, 0x01, // [0]: crop window mode enable
0x51, 0x00,
0x52, 0x00,
0x53, 0x00,
0x54, 0x00,
0x55, 0x00, //240
0x56, 0xf0,
0x57, 0x01, //320
0x58, 0x40,
////////measure Window///////
0xfe, 0x01,
0x06, 0x01,
0x07, 0x18,
0x08, 0x00,
0x09, 0xc8,
0x0a, 0x1b,
0x0b, 0x1b,
0x0c, 0x36,
0x0d, 0x36,
0xfe, 0x00,
#endif

	//global gain for range 
sccb_write(SLAVE_ID,0x70 , 0x45),
#if 1 // 25?
	/////////////banding/////////////
sccb_write(SLAVE_ID,0x05 , 0x00),//hb
sccb_write(SLAVE_ID,0x06 , 0x6a),// 0x6a
sccb_write(SLAVE_ID,0x07 , 0x00),//vb
sccb_write(SLAVE_ID,0x08 , 0x70),//
sccb_write(SLAVE_ID,0xfe , 0x01),//
sccb_write(SLAVE_ID,0x29 , 0x00),//anti-flicker step [11:8]
sccb_write(SLAVE_ID,0x2a , 0x96),//anti-flicker step [7:0]
sccb_write(SLAVE_ID,0x2b , 0x02),//exp level 0  30fps
sccb_write(SLAVE_ID,0x2c , 0x58),//             
sccb_write(SLAVE_ID,0x2d , 0x02),//exp level 1
sccb_write(SLAVE_ID,0x2e , 0x58),//             
sccb_write(SLAVE_ID,0x2f , 0x02),//exp level 2 
sccb_write(SLAVE_ID,0x30 , 0x58),//             
sccb_write(SLAVE_ID,0x31 , 0x02),//exp level 3 
sccb_write(SLAVE_ID,0x32 , 0x58),//
sccb_write(SLAVE_ID,0xfe , 0x00),//
#else
	/////////////banding/////////////
sccb_write(SLAVE_ID,0x05 , 0x00),//hb
sccb_write(SLAVE_ID,0x06 , 0x6a),//
sccb_write(SLAVE_ID,0x07 , 0x01),//vb
sccb_write(SLAVE_ID,0x08 , 0x06),//
sccb_write(SLAVE_ID,0xfe , 0x01),//
sccb_write(SLAVE_ID,0x29 , 0x00),//anti-flicker step [11:8]
sccb_write(SLAVE_ID,0x2a , 0x96),//anti-flicker step [7:0]
sccb_write(SLAVE_ID,0x2b , 0x02),//exp level 0  30fps
sccb_write(SLAVE_ID,0x2c , 0xee),//             
sccb_write(SLAVE_ID,0x2d , 0x02),//exp level 1  30fps
sccb_write(SLAVE_ID,0x2e , 0xee),//             
sccb_write(SLAVE_ID,0x2f , 0x02),//exp level 2  30fps
sccb_write(SLAVE_ID,0x30 , 0xee),//             
sccb_write(SLAVE_ID,0x31 , 0x02),//exp level 3  30fps
sccb_write(SLAVE_ID,0x32 , 0xee),//
sccb_write(SLAVE_ID,0xfe , 0x00),//
#endif

	
///////////////AWB//////////////
sccb_write(SLAVE_ID,0xfe , 0x01),
sccb_write(SLAVE_ID,0x50 , 0x00),
sccb_write(SLAVE_ID,0x4f , 0x00),
sccb_write(SLAVE_ID,0x4c , 0x01),
sccb_write(SLAVE_ID,0x4f , 0x00),
sccb_write(SLAVE_ID,0x4f , 0x00),
sccb_write(SLAVE_ID,0x4f , 0x00),
sccb_write(SLAVE_ID,0x4f , 0x00),
sccb_write(SLAVE_ID,0x4f , 0x00),
sccb_write(SLAVE_ID,0x4d , 0x30),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4d , 0x40),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4d , 0x50),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4d , 0x60),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4d , 0x70),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),	
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4f , 0x01),
sccb_write(SLAVE_ID,0x50 , 0x88),
sccb_write(SLAVE_ID,0xfe , 0x00),

	//////////// BLK//////////////////////
sccb_write(SLAVE_ID,0xfe , 0x00),
sccb_write(SLAVE_ID,0x27 , 0xb7),
sccb_write(SLAVE_ID,0x28 , 0x7F),
sccb_write(SLAVE_ID,0x29 , 0x20),
sccb_write(SLAVE_ID,0x33 , 0x20),
sccb_write(SLAVE_ID,0x34 , 0x20),
sccb_write(SLAVE_ID,0x35 , 0x20),
sccb_write(SLAVE_ID,0x36 , 0x20),
sccb_write(SLAVE_ID,0x32 , 0x08),
sccb_write(SLAVE_ID,0x3b , 0x00),
sccb_write(SLAVE_ID,0x3c , 0x00),
sccb_write(SLAVE_ID,0x3d , 0x00),
sccb_write(SLAVE_ID,0x3e , 0x00),
sccb_write(SLAVE_ID,0x47 , 0x00),
sccb_write(SLAVE_ID,0x48 , 0x00),

	//////////// block enable/////////////
sccb_write(SLAVE_ID,0x40 , 0x7f),
sccb_write(SLAVE_ID,0x41 , 0x26),
sccb_write(SLAVE_ID,0x42 , 0xfb),
sccb_write(SLAVE_ID,0x44 , 0x00),//yuv , Cb Y Cr Y
//sccb_write(SLAVE_ID,0x44 , 0xe2),//yuv // 0xe2 , Y Cb Cr
sccb_write(SLAVE_ID,0x45 , 0x00),
sccb_write(SLAVE_ID,0x46 , 0x02), // HSYNC high valid, VSYNC low valid
//sccb_write(SLAVE_ID,0x46 , 0x03), // 0x03 , HSYNC high valid, VSYNC high valid
sccb_write(SLAVE_ID,0x4f , 0x01),
sccb_write(SLAVE_ID,0x4b , 0x01),
sccb_write(SLAVE_ID,0x50 , 0x01), // mark

	/////DN & EEINTP/////
sccb_write(SLAVE_ID,0x7e , 0x0a),
sccb_write(SLAVE_ID,0x7f , 0x03),
//sccb_write(SLAVE_ID,0x80 , 0x27),
sccb_write(SLAVE_ID,0x81 , 0x15),
sccb_write(SLAVE_ID,0x82 , 0x90),
sccb_write(SLAVE_ID,0x83 , 0x02),
sccb_write(SLAVE_ID,0x84 , 0xe5), 
//sccb_write(SLAVE_ID,0x84 , 0x23), //0x23
sccb_write(SLAVE_ID,0x90 , 0x2c),
sccb_write(SLAVE_ID,0x92 , 0x02),
sccb_write(SLAVE_ID,0x94 , 0x02),
sccb_write(SLAVE_ID,0x95 , 0x35), 
//sccb_write(SLAVE_ID,0x95 , 0x60), //0x60

//===================================
	////////////YCP///////////
sccb_write(SLAVE_ID,0xd1 , 0x24),// 0x30 for front
sccb_write(SLAVE_ID,0xd2 , 0x24),// 0x30 for front
sccb_write(SLAVE_ID,0xd3 , 0x40),
sccb_write(SLAVE_ID,0xdd , 0xd3),
sccb_write(SLAVE_ID,0xde , 0x38),
sccb_write(SLAVE_ID,0xe4 , 0x88),
sccb_write(SLAVE_ID,0xe5 , 0x40),
sccb_write(SLAVE_ID,0xd7 , 0x0e),

	///////////rgb gamma ////////////
sccb_write(SLAVE_ID,0xfe , 0x00),
sccb_write(SLAVE_ID,0xbf , 0x0e),
sccb_write(SLAVE_ID,0xc0 , 0x1c),
sccb_write(SLAVE_ID,0xc1 , 0x34),
sccb_write(SLAVE_ID,0xc2 , 0x48),
sccb_write(SLAVE_ID,0xc3 , 0x5a),
sccb_write(SLAVE_ID,0xc4 , 0x6e),
sccb_write(SLAVE_ID,0xc5 , 0x80),
sccb_write(SLAVE_ID,0xc6 , 0x9c),
sccb_write(SLAVE_ID,0xc7 , 0xb4),
sccb_write(SLAVE_ID,0xc8 , 0xc7),
sccb_write(SLAVE_ID,0xc9 , 0xd7),
sccb_write(SLAVE_ID,0xca , 0xe3),
sccb_write(SLAVE_ID,0xcb , 0xed),
sccb_write(SLAVE_ID,0xcc , 0xf2),
sccb_write(SLAVE_ID,0xcd , 0xf8),
sccb_write(SLAVE_ID,0xce , 0xfd),
sccb_write(SLAVE_ID,0xcf , 0xff),

	/////////////Y gamma//////////
sccb_write(SLAVE_ID,0xfe , 0x00),
sccb_write(SLAVE_ID,0x63 , 0x00),
sccb_write(SLAVE_ID,0x64 , 0x05),
sccb_write(SLAVE_ID,0x65 , 0x0b),
sccb_write(SLAVE_ID,0x66 , 0x19),
sccb_write(SLAVE_ID,0x67 , 0x2e),
sccb_write(SLAVE_ID,0x68 , 0x40),
sccb_write(SLAVE_ID,0x69 , 0x54),
sccb_write(SLAVE_ID,0x6a , 0x66),
sccb_write(SLAVE_ID,0x6b , 0x86),
sccb_write(SLAVE_ID,0x6c , 0xa7),
sccb_write(SLAVE_ID,0x6d , 0xc6),
sccb_write(SLAVE_ID,0x6e , 0xe4),
sccb_write(SLAVE_ID,0x6f , 0xff),
	
	//////////////ASDE/////////////
sccb_write(SLAVE_ID,0xfe , 0x01),
sccb_write(SLAVE_ID,0x18 , 0x02),
sccb_write(SLAVE_ID,0xfe , 0x00),
sccb_write(SLAVE_ID,0x97 , 0x30),
sccb_write(SLAVE_ID,0x98 , 0x00),
sccb_write(SLAVE_ID,0x9b , 0x60),
sccb_write(SLAVE_ID,0x9c , 0x60),
sccb_write(SLAVE_ID,0xa4 , 0x50),
sccb_write(SLAVE_ID,0xa8 , 0x80),
sccb_write(SLAVE_ID,0xaa , 0x40),
sccb_write(SLAVE_ID,0xa2 , 0x23),
sccb_write(SLAVE_ID,0xad , 0x28),
	
	//////////////abs///////////
sccb_write(SLAVE_ID,0xfe , 0x01),
sccb_write(SLAVE_ID,0x9c , 0x00),
sccb_write(SLAVE_ID,0x9e , 0xc0),
sccb_write(SLAVE_ID,0x9f , 0x40),	
	
	////////////// AEC////////////
sccb_write(SLAVE_ID,0xfe , 0x01),
sccb_write(SLAVE_ID,0x08 , 0xa0),
sccb_write(SLAVE_ID,0x09 , 0xe8),
sccb_write(SLAVE_ID,0x10 , 0x08),
sccb_write(SLAVE_ID,0x11 , 0x21),
sccb_write(SLAVE_ID,0x12 , 0x11),
sccb_write(SLAVE_ID,0x13 , 0x45),
sccb_write(SLAVE_ID,0x15 , 0xfc),
sccb_write(SLAVE_ID,0x18 , 0x02),
sccb_write(SLAVE_ID,0x21 , 0xf0),
sccb_write(SLAVE_ID,0x22 , 0x60),
sccb_write(SLAVE_ID,0x23 , 0x30),
sccb_write(SLAVE_ID,0x25 , 0x00),
sccb_write(SLAVE_ID,0x24 , 0x14),
sccb_write(SLAVE_ID,0x3d , 0x80),
sccb_write(SLAVE_ID,0x3e , 0x40),

	////////////////AWB///////////
sccb_write(SLAVE_ID,0xfe , 0x01),
sccb_write(SLAVE_ID,0x51 , 0x88),
sccb_write(SLAVE_ID,0x52 , 0x12),
sccb_write(SLAVE_ID,0x53 , 0x80),
sccb_write(SLAVE_ID,0x54 , 0x60),
sccb_write(SLAVE_ID,0x55 , 0x01),
sccb_write(SLAVE_ID,0x56 , 0x02),
sccb_write(SLAVE_ID,0x58 , 0x00),
sccb_write(SLAVE_ID,0x5b , 0x02),
sccb_write(SLAVE_ID,0x5e , 0xa4),
sccb_write(SLAVE_ID,0x5f , 0x8a),
sccb_write(SLAVE_ID,0x61 , 0xdc),
sccb_write(SLAVE_ID,0x62 , 0xdc),
sccb_write(SLAVE_ID,0x70 , 0xfc),
sccb_write(SLAVE_ID,0x71 , 0x10),
sccb_write(SLAVE_ID,0x72 , 0x30),
sccb_write(SLAVE_ID,0x73 , 0x0b),
sccb_write(SLAVE_ID,0x74 , 0x0b),
sccb_write(SLAVE_ID,0x75 , 0x01),
sccb_write(SLAVE_ID,0x76 , 0x00),
sccb_write(SLAVE_ID,0x77 , 0x40),
sccb_write(SLAVE_ID,0x78 , 0x70),
sccb_write(SLAVE_ID,0x79 , 0x00),
sccb_write(SLAVE_ID,0x7b , 0x00),
sccb_write(SLAVE_ID,0x7c , 0x71),
sccb_write(SLAVE_ID,0x7d , 0x00),
sccb_write(SLAVE_ID,0x80 , 0x70),
sccb_write(SLAVE_ID,0x81 , 0x58),
sccb_write(SLAVE_ID,0x82 , 0x98),
sccb_write(SLAVE_ID,0x83 , 0x60),
sccb_write(SLAVE_ID,0x84 , 0x58),
sccb_write(SLAVE_ID,0x85 , 0x50),
sccb_write(SLAVE_ID,0xfe , 0x00),	
	
	////////////////LSC////////////////
sccb_write(SLAVE_ID,0xfe , 0x01),
sccb_write(SLAVE_ID,0xc0 , 0x10),
sccb_write(SLAVE_ID,0xc1 , 0x0c),
sccb_write(SLAVE_ID,0xc2 , 0x0a),
sccb_write(SLAVE_ID,0xc6 , 0x0e),
sccb_write(SLAVE_ID,0xc7 , 0x0b),
sccb_write(SLAVE_ID,0xc8 , 0x0a),
sccb_write(SLAVE_ID,0xba , 0x26),
sccb_write(SLAVE_ID,0xbb , 0x1c),
sccb_write(SLAVE_ID,0xbc , 0x1d),
sccb_write(SLAVE_ID,0xb4 , 0x23),
sccb_write(SLAVE_ID,0xb5 , 0x1c),
sccb_write(SLAVE_ID,0xb6 , 0x1a),
sccb_write(SLAVE_ID,0xc3 , 0x00),
sccb_write(SLAVE_ID,0xc4 , 0x00),
sccb_write(SLAVE_ID,0xc5 , 0x00),
sccb_write(SLAVE_ID,0xc9 , 0x00),
sccb_write(SLAVE_ID,0xca , 0x00),
sccb_write(SLAVE_ID,0xcb , 0x00),
sccb_write(SLAVE_ID,0xbd , 0x00),
sccb_write(SLAVE_ID,0xbe , 0x00),
sccb_write(SLAVE_ID,0xbf , 0x00),
sccb_write(SLAVE_ID,0xb7 , 0x07),
sccb_write(SLAVE_ID,0xb8 , 0x05),
sccb_write(SLAVE_ID,0xb9 , 0x05),
sccb_write(SLAVE_ID,0xa8 , 0x07),
sccb_write(SLAVE_ID,0xa9 , 0x06),
sccb_write(SLAVE_ID,0xaa , 0x00),
sccb_write(SLAVE_ID,0xab , 0x04),
sccb_write(SLAVE_ID,0xac , 0x00),
sccb_write(SLAVE_ID,0xad , 0x02),
sccb_write(SLAVE_ID,0xae , 0x0d),
sccb_write(SLAVE_ID,0xaf , 0x05),
sccb_write(SLAVE_ID,0xb0 , 0x00),
sccb_write(SLAVE_ID,0xb1 , 0x07),
sccb_write(SLAVE_ID,0xb2 , 0x03),
sccb_write(SLAVE_ID,0xb3 , 0x00),
sccb_write(SLAVE_ID,0xa4 , 0x00),
sccb_write(SLAVE_ID,0xa5 , 0x00),
sccb_write(SLAVE_ID,0xa6 , 0x00),
sccb_write(SLAVE_ID,0xa7 , 0x00),
sccb_write(SLAVE_ID,0xa1 , 0x3c),
sccb_write(SLAVE_ID,0xa2 , 0x50),
sccb_write(SLAVE_ID,0xfe , 0x00),
		
	///////////////CCT ///////////
sccb_write(SLAVE_ID,0xb1 , 0x12),
sccb_write(SLAVE_ID,0xb2 , 0xf5),
sccb_write(SLAVE_ID,0xb3 , 0xfe),
sccb_write(SLAVE_ID,0xb4 , 0xe0),
sccb_write(SLAVE_ID,0xb5 , 0x15),
sccb_write(SLAVE_ID,0xb6 , 0xc8),

	///////////////AWB////////////////
sccb_write(SLAVE_ID,0xfe , 0x01),
sccb_write(SLAVE_ID,0x50 , 0x00),
sccb_write(SLAVE_ID,0xfe , 0x01),
sccb_write(SLAVE_ID,0x4f , 0x00),
sccb_write(SLAVE_ID,0x4c , 0x01),
sccb_write(SLAVE_ID,0x4f , 0x00),
sccb_write(SLAVE_ID,0x4f , 0x00),
sccb_write(SLAVE_ID,0x4f , 0x00),
sccb_write(SLAVE_ID,0x4d , 0x34),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x02),
sccb_write(SLAVE_ID,0x4e , 0x02),
sccb_write(SLAVE_ID,0x4d , 0x44),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4d , 0x53),
sccb_write(SLAVE_ID,0x4e , 0x00),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4d , 0x65),
sccb_write(SLAVE_ID,0x4e , 0x04),
sccb_write(SLAVE_ID,0x4d , 0x73),
sccb_write(SLAVE_ID,0x4e , 0x20),
sccb_write(SLAVE_ID,0x4d , 0x83),
sccb_write(SLAVE_ID,0x4e , 0x20),
sccb_write(SLAVE_ID,0x4f , 0x01),
sccb_write(SLAVE_ID,0x50 , 0x88),
	/////////output//////// 
sccb_write(SLAVE_ID,0xfe , 0x00),
sccb_write(SLAVE_ID,0xf1 , 0x07),
sccb_write(SLAVE_ID,0xf2 , 0x01),
};
#else
MMP_USHORT SNR_GC0328_Reg_Init_Customer[] =
{
    0xfe, 0x80, // [7]: soft_reset, [1:0] page select
    0xfe, 0x00, // [7]: soft_reset, [1:0] page select
    
	//640x480 init registers code.                                         
0xfe, 0x80, // [7]: soft_reset, [1:0] page select
0xfc, 0x16, // [4]: digital clock enable, [2]:da25_en, [1]:da18_en
0xfc, 0x16, // [4]: digital clock enable, [2]:da25_en, [1]:da18_en
0xfc, 0x16, // [4]: digital clock enable, [2]:da25_en, [1]:da18_en
0xfc, 0x16, // [4]: digital clock enable, [2]:da25_en, [1]:da18_en
0xf1, 0x00, // [0]: VSYNC output enable, [1]: HSYNC output enable, [2]: PCLK output enable
0xf2, 0x00, // [0]: Data output enable
0xfe, 0x00, // [7]: soft_reset, [1:0] page select
0x4f, 0x00, // [0]:AEC enable
0x03, 0x00, // [3:0]: exposure[11:8]
0x04, 0xc0, // [7:0]: exposure[7:0]
0x42, 0x00, // [0]:auto Y offset, [1]:AWB enable, [2]:ABS enable, [3]:auto LSC, [4]:auto DD, [5]:auto DN, [6]:auto EE, [7]:auto saturation
0x77, 0x5a, // AWB_R_gain, 2.6 bits
0x78, 0x40, // AWB_G_gain, 2.6 bits
0x79, 0x56, // AWB_B_gain, 2.6 bits

0xfe, 0x00, // [7]: soft_reset, [1:0] page select

#if (SENSOR_OUTPUT == 3)
0x0d, 0x01, // [0]: WinH[8]
0x0e, 0x48, // [7:0]: WinH[7:0], 328
0x0f, 0x01, // [1:0]: WinW[9:8]
0x10, 0x48, // [7:0]: WinW[7:0], 328
0x09, 0x00, // [0]: Row start[8]
0x0a, 0x50, // [7:0]: Row start[7:0]
0x0b, 0x00, // [1:0]: Col start[9:8]
0x0c, 0xa0, // [7:0]: Col start[7:0]
#elif (SENSOR_OUTPUT == 4)
0x0d, 0x00, // [0]: WinH[8]
0x0e, 0xf8, // [7:0]: WinH[7:0], 248
0x0f, 0x01, // [1:0]: WinW[9:8]
0x10, 0x48, // [7:0]: WinW[7:0], 328
0x09, 0x00, // [0]: Row start[8]
0x0a, 0x78, // [7:0]: Row start[7:0]
0x0b, 0x00, // [1:0]: Col start[9:8]
0x0c, 0xa0, // [7:0]: Col start[7:0]
#else
0x0d, 0x01, // [0]: WinH[8]
0x0e, 0xe8, // [7:0]: WinH[7:0], 488
0x0f, 0x02, // [1:0]: WinW[9:8]
0x10, 0x88, // [7:0]: WinW[7:0], 648
//0x0d, 0x00, // [0]: WinH[8]
//0x0e, 0xf8, // [7:0]: WinH[7:0], 248
//0x0f, 0x01, // [1:0]: WinW[9:8]
//0x10, 0x48, // [7:0]: WinW[7:0], 328
0x09, 0x00, // [0]: Row start[8]
0x0a, 0x00, // [7:0]: Row start[7:0]
0x0b, 0x00, // [1:0]: Col start[9:8]
0x0c, 0x00, // [7:0]: Col start[7:0]
0x50, 0x00, // [0]: crop window mode enable
#endif

0x16, 0x00, // [7]:analog gain enable
0x17, 0x14, // [0]:mirror, [1]:flip, [7]:HSYNC always
0x18, 0x0e, // RSVD
0x19, 0x06, // RSVD

0x1b, 0x48, // Rsh width
0x1f, 0xC8, // RSVD
0x20, 0x01, // RSVD
0x21, 0x78, // RSVD
0x22, 0xb0, // RSVD
0x23, 0x04, //0x06  20140519 GC0328C
0x24, 0x11, // Pad driving
0x26, 0x00, // RSVD

#if (SENSOR_OUTPUT == 1)    
//0x5a, 0x0e, 
0x59, 0x22, // subsample ratio, 0x11/0x22/0x33....
0x5b, 0x00, 
0x5c, 0x00, 
0x5d, 0x00,
0x5f, 0x00,
0x60, 0x00, 
0x61, 0x00, 
0x62, 0x00, 
#elif (SENSOR_OUTPUT == 2)    
//0x5a, 0x0e, 
0x59, 0x44, // subsample ratio, 0x11/0x22/0x33....
0x5b, 0x00, 
0x5c, 0x00, 
0x5d, 0x00,
0x5f, 0x00,
0x60, 0x00, 
0x61, 0x00, 
0x62, 0x00, 
#elif (SENSOR_OUTPUT == 3)    
/////crop window///////
0x50, 0x01, // [0]: crop window mode enable
0x51, 0x00,
0x52, 0x00,
0x53, 0x00,
0x54, 0x00,
0x55, 0x01, //320
0x56, 0x40,
0x57, 0x01, //320
0x58, 0x40,
////////measure Window///////
0xfe, 0x01,
0x06, 0x08,
0x07, 0x06,
0x08, 0x58,
0x09, 0xa0,
0x0a, 0x1b,
0x0b, 0x1b,
0x0c, 0x36,
0x0d, 0x36,
0xfe, 0x00,
#elif (SENSOR_OUTPUT == 4)    
/////crop window///////
0x50, 0x01, // [0]: crop window mode enable
0x51, 0x00,
0x52, 0x00,
0x53, 0x00,
0x54, 0x00,
0x55, 0x00, //240
0x56, 0xf0,
0x57, 0x01, //320
0x58, 0x40,
////////measure Window///////
0xfe, 0x01,
0x06, 0x01,
0x07, 0x18,
0x08, 0x00,
0x09, 0xc8,
0x0a, 0x1b,
0x0b, 0x1b,
0x0c, 0x36,
0x0d, 0x36,
0xfe, 0x00,
#endif

	//global gain for range 
0x70, 0x45, // Global gain, default 0x40

/////////////banding/////////////
#if (SENSOR_OUTPUT == 3)
0x05, 0x00, // [3:0]:HBLANK[11:8]
0x06, 0x8d, // [7:0]:HBLANK[7:0]
0x07, 0x00, // [3:0]:VBLANK[11:8]
0x08, 0x32, // [7:0]:VBLANK[7:0]

0xfe, 0x01, // [7]: soft_reset, [1:0] page select
0x29, 0x00, //anti-flicker step [11:8]
0x2a, 0xe9, //anti-flicker step [7:0]
0x2b, 0x00, //exp level 0  30fps
0x2c, 0xe9, //             
0x2d, 0x00, //exp level 1
0x2e, 0xe9, //             
0x2f, 0x00, //exp level 2 
0x30, 0xe9, //             
0x31, 0x00, //exp level 3 
0x32, 0xe9, //
0x33, 0x00, //select level 0
0xfe, 0x00, // [7]: soft_reset, [1:0] page select
#elif (SENSOR_OUTPUT == 4)
0x05, 0x01, // [3:0]:HBLANK[11:8]
0x06, 0x74, // [7:0]:HBLANK[7:0]
0x07, 0x00, // [3:0]:VBLANK[11:8]
0x08, 0x0c, // [7:0]:VBLANK[7:0]

0xfe, 0x01, // [7]: soft_reset, [1:0] page select
0x29, 0x00, //anti-flicker step [11:8]
0x2a, 0xa0, //anti-flicker step [7:0]
0x2b, 0x00, //exp level 0  30fps
0x2c, 0xa0, //             
0x2d, 0x00, //exp level 1
0x2e, 0xa0, //             
0x2f, 0x00, //exp level 2 
0x30, 0xa0, //             
0x31, 0x00, //exp level 3 
0x32, 0xa0, //
0x33, 0x00, //select level 0
0xfe, 0x00, // [7]: soft_reset, [1:0] page select
#else    
0x05, 0x00, // [3:0]:HBLANK[11:8]
0x06, 0x7e, //0x6a, // [7:0]:HBLANK[7:0] , 0x7e
0x07, 0x00, // [3:0]:VBLANK[11:8]
0x08, 0x70, // [7:0]:VBLANK[7:0]

0xfe, 0x01, // [7]: soft_reset, [1:0] page select
0x29, 0x00, //anti-flicker step [11:8]
0x2a, 0x96, //anti-flicker step [7:0]
0x2b, 0x02, //exp level 0  30fps
0x2c, 0x58, //             
0x2d, 0x02, //exp level 1
0x2e, 0x58, //             
0x2f, 0x02, //exp level 2 
0x30, 0x58, //             
0x31, 0x02, //exp level 3 
0x32, 0x58, //
0xfe, 0x00, // [7]: soft_reset, [1:0] page select
#endif

	///////////////AWB//////////////
0xfe, 0x01, // [7]: soft_reset, [1:0] page select
0x50, 0x00, // [7]:PRE_enable
0x4f, 0x00,
0x4c, 0x01,
0x4f, 0x00,
0x4f, 0x00,
0x4f, 0x00,
0x4f, 0x00,
0x4f, 0x00,
0x4d, 0x30,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,
0x4d, 0x40,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,
0x4d, 0x50,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,
0x4d, 0x60,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,
0x4d, 0x70,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,
0x4e, 0x04,	
0x4e, 0x04,
0x4e, 0x04,
0x4f, 0x01,
0x50, 0x88, // [7]:PRE_enable
0xfe, 0x00, // [7]: soft_reset, [1:0] page select

	//////////// BLK//////////////////////
0xfe, 0x00, // [7]: soft_reset, [1:0] page select
0x27, 0xb7, // [0]: offset enable, [1]: dark current measure enable, [7]: dark current mode
0x28, 0x7F, // [6:0]: Blk value limit
0x29, 0x20,
0x33, 0x20,
0x34, 0x20,
0x35, 0x20,
0x36, 0x20,
0x32, 0x08,
0x3b, 0x00,
0x3c, 0x00,
0x3d, 0x00,
0x3e, 0x00,
0x47, 0x00,
0x48, 0x00,

	//////////// block enable/////////////
0x40, 0x7f, // [0]: Lens shading, [1]:Defect, [2]: NR, [3]: Interpolation, [4]: EE, [5]:CC, [6]:gamma, [7]:middle gamma
0x41, 0x26, // [0]: block skin, [1]:Y gamma, [2]: auto gray, [3]:new skin, [4]: skin Y, [5]:skin, [6]: low light Y
0x42, 0xfb, // [0]:auto Y offset, [1]:AWB enable, [2]:ABS enable, [3]:auto LSC, [4]:auto DD, [5]:auto DN, [6]:auto EE, [7]:auto saturation
0x44, 0xe2, // [4:0]: output data mode, YCbYCr, [6]: Smooth Y
0x45, 0x00,
0x46, 0x03, // [0]: VS pol, [1]: HS pol, [2]: PCLK pol,
0x4f, 0x01, // [0]:AEC enable
0x4b, 0x01, // [0]: update gain mode, [1]: AWB gain mode

/////DN & EEINTP/////
0x7e, 0x0a,
0x7f, 0x03,
0x80, 0x27, //  20140915
0x81, 0x15,
0x82, 0x90,
0x83, 0x02,
0x84, 0x23, // 0x22 20140915
0x90, 0x2c,
0x92, 0x02,
0x94, 0x02,
0x95, 0x60,  // Edge1[7:4] & Edge2[3:0] effect

	////////////YCP///////////
0xd1, 0x24,// 0x30 for front
0xd2, 0x24,// 0x30 for front
0xd3, 0x40,
0xdd, 0xd3,
0xde, 0x38,
0xe4, 0x88,
0xe5, 0x40,
0xd7, 0x0e,

	///////////rgb gamma ////////////
0xfe, 0x00, // [7]: soft_reset, [1:0] page select
0xbf, 0x0e,
0xc0, 0x1c,
0xc1, 0x34,
0xc2, 0x48,
0xc3, 0x5a,
0xc4, 0x6e,
0xc5, 0x80,
0xc6, 0x9c,
0xc7, 0xb4,
0xc8, 0xc7,
0xc9, 0xd7,
0xca, 0xe3,
0xcb, 0xed,
0xcc, 0xf2,
0xcd, 0xf8,
0xce, 0xfd,
0xcf, 0xff,

	/////////////Y gamma//////////
0xfe, 0x00, // [7]: soft_reset, [1:0] page select
0x63, 0x00,
0x64, 0x05,
0x65, 0x0b,
0x66, 0x19,
0x67, 0x2e,
0x68, 0x40,
0x69, 0x54,
0x6a, 0x66,
0x6b, 0x86,
0x6c, 0xa7,
0x6d, 0xc6,
0x6e, 0xe4,
0x6f, 0xff,
	
// ASDE (auto saturation de-noise and edge enhancement)
0xfe, 0x01, // [7]: soft_reset, [1:0] page select
0x18, 0x02, // [2:0]: luma value divider

0xfe, 0x00, // [7]: soft_reset, [1:0] page select
0x97, 0x30,
0x98, 0x00,
0x9b, 0x60,
0x9c, 0x60,
0xa4, 0x50,
0xa8, 0x80,
0xaa, 0x40,
0xa2, 0x23,
0xad, 0x28,
	
	//////////////abs///////////
0xfe, 0x01, // [7]: soft_reset, [1:0] page select
0x9c, 0x00,
0x9e, 0xc0,
0x9f, 0x40,	
	
	////////////// AEC////////////
0xfe, 0x01, // [7]: soft_reset, [1:0] page select
#if (SENSOR_OUTPUT != 3) && (SENSOR_OUTPUT != 4)    
0x08, 0xa0, // Window setting for AEC&AWB, Big_win_width, x4
0x09, 0xe8, // Window setting for AEC&AWB, Big_win_height, x4
#endif
0x10, 0x08, // AEC_mode1
0x11, 0x21, // AEC_mode2
0x12, 0x11, // AEC_mode3
0x13, 0x45,
0x15, 0xfc,
0x18, 0x02,
0x21, 0xf0,
0x22, 0x60,
0x23, 0x30,
0x25, 0x00,
0x24, 0x14,
0x3d, 0x80,
0x3e, 0x40,

	////////////////AWB///////////
0xfe, 0x01, // [7]: soft_reset, [1:0] page select
0x51, 0x88,
0x52, 0x12,
0x53, 0x80,
0x54, 0x60,
0x55, 0x01,
0x56, 0x02,
0x58, 0x00,
0x5b, 0x02,
0x5e, 0xa4,
0x5f, 0x8a,
0x61, 0xdc,
0x62, 0xdc,
0x70, 0xfc,
0x71, 0x10,
0x72, 0x30,
0x73, 0x0b,
0x74, 0x0b,
0x75, 0x01,
0x76, 0x00,
0x77, 0x40,
0x78, 0x70,
0x79, 0x00,
0x7b, 0x00,
0x7c, 0x71,
0x7d, 0x00,
0x80, 0x70,
0x81, 0x58,
0x82, 0x98,
0x83, 0x60,
0x84, 0x58,
0x85, 0x50,
0xfe, 0x00,	// [7]: soft_reset, [1:0] page select
	
	////////////////LSC////////////////
0xfe, 0x01, // [7]: soft_reset, [1:0] page select
0xc0, 0x10,
0xc1, 0x0c,
0xc2, 0x0a,
0xc6, 0x0e,
0xc7, 0x0b,
0xc8, 0x0a,
0xba, 0x26,
0xbb, 0x1c,
0xbc, 0x1d,
0xb4, 0x23,
0xb5, 0x1c,
0xb6, 0x1a,
0xc3, 0x00,
0xc4, 0x00,
0xc5, 0x00,
0xc9, 0x00,
0xca, 0x00,
0xcb, 0x00,
0xbd, 0x00,
0xbe, 0x00,
0xbf, 0x00,
0xb7, 0x07,
0xb8, 0x05,
0xb9, 0x05,
0xa8, 0x07,
0xa9, 0x06,
0xaa, 0x00,
0xab, 0x04,
0xac, 0x00,
0xad, 0x02,
0xae, 0x0d,
0xaf, 0x05,
0xb0, 0x00,
0xb1, 0x07,
0xb2, 0x03,
0xb3, 0x00,
0xa4, 0x00,
0xa5, 0x00,
0xa6, 0x00,
0xa7, 0x00,
0xa1, 0x3c,
0xa2, 0x50,
0xfe, 0x00, // [7]: soft_reset, [1:0] page select
		
	///////////////CCM ///////////
0xb1, 0x12,
0xb2, 0xf5,
0xb3, 0xfe,
0xb4, 0xe0,
0xb5, 0x15,
0xb6, 0xc8,

	/*   /////skin CC for front //////
0xb1, 0x00,
0xb2, 0x00,
0xb3, 0x00,
0xb4, 0xf0,
0xb5, 0x00,
0xb6, 0x00,
	*/

	///////////////AWB////////////////
0xfe, 0x01, // [7]: soft_reset, [1:0] page select
0x50, 0x00, // [7]:PRE_enable

0xfe, 0x01, // [7]: soft_reset, [1:0] page select
0x4f, 0x00,
0x4c, 0x01,
0x4f, 0x00,
0x4f, 0x00,
0x4f, 0x00,
0x4d, 0x34,
0x4e, 0x04,
0x4e, 0x04,
0x4e, 0x02,
0x4e, 0x02,
0x4d, 0x44,
0x4e, 0x04,
0x4e, 0x04,
0x4e, 0x04,
0x4d, 0x53,
0x4e, 0x00,
0x4e, 0x04,
0x4e, 0x04,
0x4e, 0x04,
0x4d, 0x65,
0x4e, 0x04,
0x4d, 0x73,
0x4e, 0x20,
0x4d, 0x83,
0x4e, 0x20,
0x4f, 0x01,
0x50, 0x88, // [7]:PRE_enable

	/////////output//////// 
0xfe, 0x00, // [7]: soft_reset, [1:0] page select

0x05,0,    //HB
0x06,0x72,
0x07,0,    //VB
0x08,0x70,
0x11,0x22, //reversed  sh_delay?22-34 66-37

0xf1, 0x07, // [0]: VSYNC output enable, [1]: HSYNC output enable, [2]: PCLK output enable
0xf2, 0x01, // [0]: Data output enable
};

#endif

void SNR_GC0328_InitSensor_Customer(void) {
    // implement your initialize sensor routine here ==============================================
    ISP_UINT32 i;

    //MMPF_OS_Sleep_MS(50); 

    // set register...........
    for (i = 0; i < sizeof(SNR_GC0328_Reg_Init_Customer)/4; i++) {
        gsSensorFunction->MMPF_Sensor_SetReg(SNR_GC0328_Reg_Init_Customer[i*2], SNR_GC0328_Reg_Init_Customer[i*2+1]);
       // gsSensorFunction->MMPF_Sensor_GetReg(SNR_GC0328_Reg_Init_Customer[i*2], &o);
        //dbg_printf(0, "%x %x %x\r\n", SNR_GC0328_Reg_Init_Customer[i*2], SNR_GC0328_Reg_Init_Customer[i*2+1], o);
        //MMPF_OS_Sleep_MS(1);
    }
}


void SNR_GC0328_SetSensorAddMode_Customer(ISP_UINT8 enable)
{

}
MMP_USHORT SNR_GC0328_Reg_1280x720_Customer[] = 
{
0,0
};

void SNR_GC0328_SetSensorResolution_Customer(ISP_SENSOR_RESOL res)
{
    // implement your change sensor resolution routine here =======================================

    MMP_ULONG VIFGrab_H_Start, VIFGrab_H_Length, VIFGrab_V_Start, VIFGrab_V_Length;

    switch (res) {
    case ISP_SENSOR_RESOL_1600x1200:
    case ISP_SENSOR_RESOL_1280x960:
    case ISP_SENSOR_RESOL_1280x720:
    case ISP_SENSOR_RESOL_640x480:
    case ISP_SENSOR_RESOL_320x240:
    case ISP_SENSOR_RESOL_160x120:

        // set register...........
        //for (i = 0; i < VR_ARRSIZE(SNR_GC0328_Reg_1280x720_Customer)/2; i++) {
        //    gsSensorFunction->MMPF_Sensor_SetReg(SNR_GC0328_Reg_1280x720_Customer[i*2], SNR_GC0328_Reg_1280x720_Customer[i*2+1]);
        //}

        // set target fps and corresponding sensor vsync
        //ISP_IF_AE_SetSensorVsync(828, 30*10);//bossino fix m2ts AV sync @0928 ISP_IF_SNR_SetFPS(0x0348, 30);

        // set vif grab range which is fetched to ISP (for lens shading and 3A window calculation)
        VIFGrab_H_Start     = 1;
        VIFGrab_H_Length    = gsSensorPreviewWidth[1];
        VIFGrab_V_Start     = 1;
        VIFGrab_V_Length    = gsSensorPreviewHeight[1];

        g_SNR_LineCntPerSec = (SENSOR_RESOLUTION_HEIGHT+8)*30; // 680*30//207 * 120;    //???? 1sec H_s

        ISP_IF_AE_SetMaxSensorFPSx10(300);

#if 0//def ZDW_SET_EXPOSURE
		ISP_IF_IQ_SetISPInputLength(VIFGrab_H_Length - 8, VIFGrab_V_Length - 8);
#else
        ISP_IF_IQ_SetISPInputLength(VIFGrab_H_Length, VIFGrab_V_Length);
#endif
        // set scaler downsample rate (for scaler calculation)
        //ISP_IF_SNR_SetDownSample(1, 1);

        // set color id
        #if SENSOR_ROTATE_180
        ISP_IF_IQ_SetColorID(3);
        #else
        ISP_IF_IQ_SetColorID(0);// mirror is 3
        #endif

        // calcuate shading ratio
        {
            ISP_UINT32 base_x, base_y;
            ISP_UINT32 x_scale_n = 0x200;
            ISP_UINT32 y_scale_n = 0x200;
            ISP_IF_IQ_GetCaliBase(&base_x, &base_y);

            x_scale_n = VIFGrab_H_Length * 0x200 / base_x;
            y_scale_n = VIFGrab_V_Length * 0x200 / base_y;

            ISP_IF_IQ_SetCaliRatio(	x_scale_n,  //x_scale_n, 
                                    0x200,      //x_scale_m, 
                                    0,          //x_offset, 
                                    y_scale_n,  //y_scale_n, 
                                    0x200,      //y_scale_m, 
                                    0);         //y_offset
        }
        break;
    }
	
    // end of your implementation =================================================================

    // set VIF OPR (Actual sensor output size)
    {
        AITPS_VIF  pVIF = AITC_BASE_VIF;
        volatile MMP_BYTE* pISP = (volatile MMP_BYTE*)AITC_BASE_ISP;
        //MMP_UBYTE   vif_id = 0;

        pVIF->VIF_GRAB[vif_id].PIXL_ST = VIFGrab_H_Start;
        pVIF->VIF_GRAB[vif_id].PIXL_ED = VIFGrab_H_Start + VIFGrab_H_Length -1;
        pVIF->VIF_GRAB[vif_id].LINE_ST = VIFGrab_V_Start ;
        pVIF->VIF_GRAB[vif_id].LINE_ED = VIFGrab_V_Start + VIFGrab_V_Length -1;
        pVIF->VIF_INT_LINE_NUM_0[vif_id] = VIFGrab_V_Length - 31;//61;//121;

#if 1	
        dbg_printf(3,"ViF(xs,xe,ys,ye)=(%d,%d,%d,%d)\r\n",pVIF->VIF_GRAB[vif_id].PIXL_ST,pVIF->VIF_GRAB[vif_id].PIXL_ED,pVIF->VIF_GRAB[vif_id].LINE_ST,pVIF->VIF_GRAB[vif_id].LINE_ED);
        dbg_printf(3, "[0] VIFGrab_H_Length = %d, VIFGrab_V_Length = %d\r\n", VIFGrab_H_Length, VIFGrab_V_Length); 
#endif

        if (m_gsISPCoreID == 868) {
            // ISP pipeline selection
            //APICAL_XBYTE[APICAL_CTL_REG1] &= ~(0x80); // clear auto size
            pISP[0x0B] = 0x30;
            pISP[0x09] = 0x0C;

            // IP ColorID setting
            //pISP[0x09] &= ~(0xF0);
            //pISP[0x09] |= (ISP_IF_SNR_GetColorID() == 0 ? 3 : (ISP_IF_SNR_GetColorID() == 1 ? 2 : (ISP_IF_SNR_GetColorID() == 2 ? 1: 0))) * (0x50);
        }
    }

    //================
    // set iq (NR, Edge, CCM, Gamma, etc.) and functions (saturation, contrast, sharpness, hue, etc.)
    ISP_IF_IQ_SetAll();

    // SetBeforePreview and SetBeforeCapture should be called after getting new configurations of the current resolution
    if (gSystemMode  == VENUS_SYSTEM_MODE_SNAPSHOT) {
        // update AE before capture
        ISP_IF_AE_UpdateBeforeCapture();

        // update AWB before capture
        ISP_IF_AWB_UpdateBeforeCapture();

        // special settings for capture could be set here =============================================
        {
        }
        // end of special settings ====================================================================
    } else if (gSystemMode == VENUS_SYSTEM_MODE_PREVIEW) {
        // update AE before preview
        ISP_IF_AE_UpdateBeforePreview();

        // update AWB before preview
        ISP_IF_AWB_UpdateBeforePreview();
    }

    // set direction (color ID, orientation, etc.)
    ISP_IF_IQ_SetDirection(ISP_IQ_DIRECTION_ORIGINAL);

    // set exposure parameters
    ISP_IF_IQ_SetAWBGains(ISP_IF_AWB_GetGainR(), ISP_IF_AWB_GetGainG(), ISP_IF_AWB_GetGainB(), ISP_IF_AWB_GetGainBase());

    // update ISP window
    ISP_IF_IQ_UpdateInputSize();

    // check if modules are bypassed
    ISP_IF_IQ_CheckBypass();

    // force update iq to hardware
    ISP_IF_IQ_UpdateOprtoHW(ISP_IQ_SWITCH_ALL, 1);

}
#if (MotionDetection == 1)
static MMP_ULONG AEAcc_temp[9]={0xFFFF};
extern MMP_ULONG AEAcc_Buffer[9];
void COLOR_StoreAEAcc(void)
{
    MMP_SHORT i;
    for(i=0;i<9;i++)
    {
        AEAcc_temp[i] = AEAcc_Buffer[i];
    }
}

void COLOR_CopyAEAcc(MMP_ULONG* addr)
{
    struct _FRAME_H264_PH *header = (struct _FRAME_H264_PH *)addr;
    MMP_SHORT i;
    for(i=0;i<9;i++)
    {
    	header->dwAEAcc[i] = AEAcc_temp[i];
    }
    header->dwAELightCond = ISP_IF_AE_GetLightCond();
    header->dwAWB_GainRValue = ISP_IF_AWB_GetGainR();
    header->dwAWB_GainBValue  = ISP_IF_AWB_GetGainB();
}
#endif

#if SUPPORT_AUTO_FOCUS
void MOTOR_GC0328_VCM_InitMotor_Customer(void)
{
    //uint16 ret;
}
void MOTOR_GC0328_VCM_EnterStandby_Customer(MMP_USHORT af_pos)
{
    //VR_Motor_SmoothMove(af_pos);

}

void MOTOR_GC0328_VCM_SetAFPosition_Customer(MMP_USHORT af_pos)
{

    //dbg_printf(3, "af_pos = %d\r\n", af_pos);
}

MMP_UBYTE MOTOR_GC0328_VCM_CheckAFreachPosition_Customer(MMP_USHORT af_pos)
{
    
    return 1;
    
}
#endif

#if (SENSOR_ID_GC0328== 0)
MMPF_SENSOR_FUNCTION  *SensorFunction_Module0 = &SensorFunction_GC0328;
#endif

#if (SENSOR_ID_GC0328== 1)
MMPF_SENSOR_FUNCTION  *SensorFunction_Module1 = &SensorFunction_GC0328;
#endif

void MMPF_SetPrivacyMask(ISP_UINT8 en, ISP_UINT8* privacymask){

    volatile MMP_UBYTE* REG_BASE_B = (volatile MMP_UBYTE*)0x80000000;
    ISP_UINT16 i, j;
    ISP_UINT8 cs_bank[4] = {0, 4, 168, 172};

    ISP_UINT16 cslut_offset[7*5]= {   0,   8,  16,  24,  32,  40,  48,	
                                    336, 344, 352, 360, 368, 376, 384,
                                    672, 680, 688, 696, 704, 712, 720,
                                   1008,1016,1024,1032,1040,1048,1056,
                                   1344,1352,1360,1368,1376,1384,1392 };

    if(en ==0) return;
	
    for(i = 0; i < 5; i++){
        for(j = 0; j < 7; j++){
            if(privacymask[i * 7 + j]==1){//((i ==2 && j == 3) || (i ==0 && j == 0)){//
                *((volatile MMP_U_LONG*)(*((volatile MMP_U_LONG*)0x80000DF8) + cslut_offset[7 * i + j] + cs_bank[0])) = 0;
                *((volatile MMP_U_LONG*)(*((volatile MMP_U_LONG*)0x80000DF8) + cslut_offset[7 * i + j] + cs_bank[1])) = 0;
                *((volatile MMP_U_LONG*)(*((volatile MMP_U_LONG*)0x80000DF8) + cslut_offset[7 * i + j] + cs_bank[2])) = 0;			
                *((volatile MMP_U_LONG*)(*((volatile MMP_U_LONG*)0x80000DF8) + cslut_offset[7 * i + j] + cs_bank[3])) = 0;							
            }
        }
    }	
    REG_BASE_B[0xdf0] |= 0x02;
}


#endif  //BIND_SENSOR_GC0328
#endif
